Альтернативный подход к множественным левым соединениям
У меня есть следующие запросы для подсчета продаж по маршруту
SELECT DISTINCT q.sales_route,
y.yesterday,
t.today
FROM tblquotesnew q
left join (SELECT tblquotesnew.sales_route,
Count(tblquotesnew.sales_route) AS Yesterday
FROM tblquotesnew
WHERE tblquotesnew.date_sent_to_registrations =
Trunc(SYSDATE - 1)
AND sales_route IS NOT NULL
GROUP BY tblquotesnew.sales_route) y
ON q.sales_route = y.sales_route
left join (SELECT tblquotesnew.sales_route,
Count(tblquotesnew.sales_route) AS Today
FROM tblquotesnew
WHERE tblquotesnew.date_sent_to_registrations =
Trunc(SYSDATE)
AND sales_route IS NOT NULL
GROUP BY tblquotesnew.sales_route) t
ON q.sales_route = t.sales_route
Затем у меня есть еще 6 левых соединений для подсчета текущей и предыдущей недели, месяца и года.
Этот подход работает, но мне было интересно, если это более эффективный (с точки зрения строк кода) способ объединения этих данных?
2 ответа
Решение
Я думаю, что вам просто нужно условное агрегирование:
select q.sales_route,
sum(case when q.date_sent_to_registrations = trunc(SYSDATE - 1)
then 1 else 0
end) as yesterday,
sum(case when q.date_sent_to_registrations = trunc(SYSDATE)
then 1 else 0
end) as today
from tblquotesnew q
group by sales_route
Вы можете использовать условную агрегацию
SELECT sales_route,
sum(CASE WHEN date_sent_to_registrations = Trunc(SYSDATE)
AND sales_route IS NOT NULL
THEN 1 ELSE 0 END) today,
sum(CASE WHEN date_sent_to_registrations = Trunc(SYSDATE - 1)
AND sales_route IS NOT NULL
THEN 1 ELSE 0 END) yesterday
FROM tblquotesnew
GROUP BY sales_route
условное агрегирование приводит к одному последовательному сканированию вашей таблицы, которое может быть нормальным во многих случаях. Альтернативное решение заключается в использовании подзапросов SELECT
который может быть иногда более эффективным. Например, если вы обращаетесь к небольшому фрагменту данных и можете создавать индексы для его поддержки.