#sql #postgresql #count #sum #aggregate-functions
#sql #PostgreSQL #количество #Сумма #агрегатные функции
Вопрос:
Я все еще новичок в изучении PSQL и задавался вопросом, как соединить по ЛЕВОМУ КРАЮ два отдельных запроса, которые я извлекаю из одного и того же материализованного представления.
Вот мой первый запрос:
select rep_name, Count(enroll_date) new_orders, Sum(invoice_total) contract_total, Avg(invoice_total) avg_contract_total
from recent_billing_mat_view
where
enroll_date <= current_date
AND enroll_date > (current_date - '30 days'::interval)
AND product_type = 'CTF'
AND pay_type <> 'Credit'
group by rep_name
И он возвращает следующее:
rep_name new_orders contract_total avg_contract_total
"Alyssa" 9 2515 279.444444444444
"Carlos" 24 6585 274.375
"Cheryle" 14 4871 347.928571428571
"Nicholas" 19 4775 251.315789473684
"Piero" 13 4405.5 338.884615384615
"Susan" 15 4450.5 296.7
"Valerie" 16 4640 290
"Yelitza" 12 3607 300.583333333333
Вот мой второй запрос:
select rep_name, Count(enroll_date) orders_paid
from recent_billing_mat_view
where
enroll_date <= current_date
AND enroll_date > (current_date - '30 days'::interval)
AND product_type = 'CTF'
AND pay_type <> 'Credit'
AND amount_paid > 0
group by rep_name
И он возвращает следующее:
rep_name orders_paid
"Alyssa" 6
"Carlos" 16
"Cheryle" 8
"Nicholas" 14
"Piero" 9
"Susan" 8
"Valerie" 10
"Yelitza" 9
Я использую 2-й запрос, чтобы получить количество всех заказов, которые были оплачены за каждого представителя, и я хочу присоединиться к нему в первом запросе. В настоящее время я получаю сообщение об ошибке: ОШИБКА: синтаксическая ошибка на или рядом с «LEFT».
Вот с чем я работаю:
select r.rep_name, Count(enroll_date) new_orders, Sum(invoice_total) contract_total, Avg(invoice_total) avg_contract_total
from recent_billing_mat_view r
where
r.enroll_date <= current_date
AND r.enroll_date > (current_date - '30 days'::interval)
AND r.product_type = 'CTF'
AND r.pay_type <> 'Credit'
group by r.rep_name
LEFT JOIN (
select Count(enroll_date) orders_paid
from recent_billing_mat_view p
where
p.enroll_date <= current_date
AND p.enroll_date > (current_date - '30 days'::interval)
AND p.product_type = 'CTF'
AND p.pay_type <> 'Credit'
AND p.amount_paid > 0
group by rep_name
) as p On r.rep_name = p.rep_name
Как бы я хотел, чтобы результаты выглядели:
rep_name new_orders contract_total avg_contract_total orders_paid
"Alyssa" 9 2515 279.444444444444 6
"Carlos" 24 6585 274.375 16
"Cheryle" 14 4871 347.928571428571 8
"Nicholas" 19 4775 251.315789473684 14
"Piero" 13 4405.5 338.884615384615 9
"Susan" 15 4450.5 296.7 8
"Valerie" 16 4640 290 10
"Yelitza" 12 3607 300.583333333333 9
Чего мне здесь не хватает? Есть ли лучший способ сделать это без ЛЕВОГО СОЕДИНЕНИЯ?
Спасибо!
Ответ №1:
Второй запрос полностью идентичен первому, за исключением одного условия в where
предложении. Вы можете просто использовать условную агрегацию:
select rep_name,
count(*) new_orders,
sum(invoice_total) contract_total,
avg(invoice_total) avg_contract_total,
count(*) filter(where amount_paid > 0) orders_paid
from recent_billing_mat_view
where
enroll_date <= current_date
and enroll_date > current_date - '30 days'::interval
and product_type = 'CTF'
and pay_type <> 'Credit'
group by rep_name
Примечание: способ построения вашего enroll_date
запроса никогда не может быть null
(потому что он фильтруется в where
предложении): so count(enroll_date)
эквивалентно count(*)
и более эффективно.