Я получил (ОШИБКА: более одной строки, возвращенной подзапросом, использованным в качестве выражения) или неверный счет / сумма внутри подзапроса - PullRequest
0 голосов
/ 06 февраля 2020

Я хотел бы сделать запрос, который покажет мне общее количество и сумму продаж, и для 2 работников в тех же строках.

Когда я не использую group by в подзапросе, я получаю подсчет общих продаж для этого работника, не подсчитываемых за каждый месяц. Но когда я пытаюсь использовать предложение Group By в подзапросе, оно показывает мне эту ошибку:

PG :: CardinalityViolation:
ОШИБКА: более одной строки, возвращенной подзапросом, используемым в качестве выражения

И это имеет смысл, но как я могу посчитать и суммировать объем продаж в месяц для каждого работника? Есть ли возможность перенести значение предложения Group By из запроса в подзапрос? Должен ли я использовать подзапрос для этой конкретной проблемы c или, может быть, я могу как-то упростить ее?

SELECT 
    DATE_PART('month', payment_date) as month, 
    COUNT(payment_id) AS total_count,
    SUM(amount) AS total_amount,
    (SELECT COUNT(payment_id)
     FROM payment
     WHERE staff_id = 1
     GROUP BY DATE_PART('month', payment_date)) AS mike_count,
    (SELECT SUM(amount)
     FROM payment
     WHERE staff_id = 1
     GROUP BY DATE_PART('month', payment_date)) AS mike_amount,
    (SELECT COUNT(payment_id)
     FROM payment
     WHERE staff_id = 2
     GROUP BY DATE_PART('month', payment_date)) AS jon_count,
    (SELECT SUM(amount)
     FROM payment
     WHERE staff_id = 2
     GROUP BY DATE_PART('month', payment_date)) AS jon_amount
FROM 
    payment
GROUP BY  
    DATE_PART('month', payment_date)
ORDER BY 
    DATE_PART('month', payment_date);

Это результат без предложения group by в подзапросах:

month   |total_count    |total_amount   |mike_count |mike_amount    |jon_count  |jon_amount
2       |2016           |0.835184E4     |7292       |0.3025212E5    |7304       |0.3105992E5
3       |5644           |0.2388656E5    |7292       |0.3025212E5    |7304       |0.3105992E5
4       |6754           |0.2855946E5    |7292       |0.3025212E5    |7304       |0.3105992E5
5       |182            |0.51418E3      |7292       |0.3025212E5    |7304       |0.3105992E5

1 Ответ

2 голосов
/ 06 февраля 2020

Вместо этого используйте условное агрегирование:

SELECT DATE_PART('month', payment_date) as month, 
       count(payment_id) AS total_count,
       SUM(amount) AS total_amount,
       SUM(CASE WHEN staff_id = 1 THEN 1 ELSE 0 END) as  mike_count,
       SUM(CASE WHEN staff_id = 1 THEN amount ELSE 0 END) as  mike_amount,
       SUM(CASE WHEN staff_id = 2 THEN 1 ELSE 0 END) as jon_count,
       SUM(CASE WHEN staff_id = 2 THEN amount ELSE 0 END) as jon_amount
FROM payment
GROUP BY DATE_PART('month', payment_date)
ORDER BY DATE_PART('month', payment_date);

DATE_PART() предполагает, что вы используете Postgres. Если это так, я бы порекомендовал пункт FILTER:

SELECT DATE_PART('month', payment_date) as month, 
       COUNT(payment_id) AS total_count,
       SUM(amount) AS total_amount,
       COUNT(*) FILTER (WHERE staff_id = 1) as  mike_count,
       SUM(amount) FILTER (WHERE staff_id = 1) as  mike_amount,
       COUNT(*) FILTER (WHERE staff_id = 2) as jon_count,
       SUM(amount) FILTER (WHERE staff_id = 2) as jon_amount
FROM payment
GROUP BY DATE_PART('month', payment_date)
ORDER BY DATE_PART('month', payment_date);
...