我得到了(错误:子查询返回的多于一行用作表达式)或子查询内部的计数/总和不正确

问题描述 投票:0回答:2

我想进行查询,以显示在同一行中有2名工人的总数和销售总额。

[当我不在子查询中使用分组依据时,我得到了该工人的总销售额的计数,而该计数未按月计算。但是,当我尝试在子查询中使用Group By子句时,会显示此错误:

PG :: CardinalityViolation:错误:用作表达式的子查询返回的一行以上

这很有意义,但是我如何计算每个工人每月的销售额和总和?是否有可能将Group By子句的值从查询转移到子查询?我应该针对此特定问题使用子查询,还是可以通过某种方式使它更容易?

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
sql group-by subquery
2个回答
0
投票

改为使用条件聚合:

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);

0
投票

您需要通过使month值匹配来将子查询与主查询相关联;那么您可以删除GROUP BY子句:

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 p2
    WHERE staff_id =1
      AND DATE_PART('month', p2.payment_date) = DATE_PART('month', p1.payment_date)
  ) AS mike_count,
  ( SELECT SUM(amount)
    FROM payment p2
    WHERE staff_id =1
      AND DATE_PART('month', p2.payment_date) = DATE_PART('month', p1.payment_date)
  ) AS mike_amount,
  ( SELECT COUNT(payment_id)
    FROM payment p2
    WHERE staff_id =2
      AND DATE_PART('month', p2.payment_date) = DATE_PART('month', p1.payment_date)
  ) AS jon_count,
  ( SELECT SUM(amount)
    FROM payment
    WHERE staff_id =2
      AND DATE_PART('month', p2.payment_date) = DATE_PART('month', p1.payment_date)
  ) AS jon_amount
FROM payment p1
GROUP BY DATE_PART('month', payment_date)
ORDER BY DATE_PART('month', payment_date);
© www.soinside.com 2019 - 2024. All rights reserved.