是否有可能将Group by,Having和Sum结合起来?

时间:2021-01-01 20:10:07

I have a table:

我有一张桌子:

------------------------
|id|p_id|desired|earned|
------------------------
|1 | 1  |  5    |  7   |
|2 | 1  |  15   |  0   |
|3 | 1  |  10   |  0   |
|4 | 2  |  2    |  3   |
|5 | 2  |  2    |  3   |
|6 | 2  |  2    |  3   |
------------------------

I need to make some calculations, and try to make it in one not really complex request, otherwise I know how to calculate it with numbers of requests. I need resulted table like following:

我需要进行一些计算,并尝试在一个非常复杂的请求中进行计算,否则我知道如何使用请求数来计算它。我需要结果表如下:

---------------------------------------------------------
|p_id|total_earned|    AVG   |      Count     |  SUM    |
|    |            | (desired)|(if earned != 0)|(desired)|
---------------------------------------------------------
|  1 |      7     |     10   |       1        |    30   |
|  2 |      9     |      2   |       3        |    6    |
---------------------------------------------------------

I build so far:

我到目前为止构建:

SELECT p_id, SUM(earned), AVG(desired), Sum(desired) 
FROM table GROUP BY p_id

But I can't figure out how to calculate the number of grouped records with conditions. I can get this number with HAVING but in separated request.

但我无法弄清楚如何计算带条件的分组记录数。我可以通过HAVING得到这个号码,但是在单独的请求中。

I almost sure what SQL should have this power.

我几乎可以肯定SQL应该拥有这种能力。

4 个解决方案

#1


12  

You can use CASE expression for this.

您可以使用CASE表达式。

Try this,

SELECT p_id
    ,SUM(earned) AS total_earned
    ,AVG(desired) AS avg_desired
    ,COUNT(CASE WHEN Earned!=0 THEN 1 END) AS earned_count
    ,SUM(desired) AS sum_desired
FROM table
GROUP BY p_id;

#2


3  

A shorter alternative to CASE is

CASE的一个较短的替代品是

SELECT p_id,
    SUM(earned) AS total_earned,
    AVG(desired) AS average_desired,
    COUNT(earned != 0 OR NULL) AS earned_count,
    SUM(desired) AS sum_desired
FROM table GROUP BY p_id;

because NULLs are not counted.

因为NULL不计算在内。

#3


3  

You have almost done your query just add conditional aggregation with help of case expression for earned count

您几乎完成了查询,只需添加条件聚合,并在案例表达式的帮助下为获得的计数添加

SELECT 
           p_id,
           SUM(earned) [total_earned],
           AVG(desired) [desired],
           SUM(CASE WHEN earned <> 0 THEN 1 ELSE 0 END) [COUNT],
           SUM(desired) [SUM] FROM <table>
 GROUP BY p_id

Result

p_id    total_earned  desired   COUNT  SUM
1       7             10        1      30
2       9             2         3      6

#4


1  

NULLIF() is standard SQL and probably shortest:

NULLIF()是标准SQL,可能是最短的:

SELECT p_id
     , count(NULLIF(earned, 0)) AS earned_count
  -- , more ...
FROM   table
GROUP  BY 1;

count() only counts non-null values.

count()仅计算非空值。

More variants:

#1


12  

You can use CASE expression for this.

您可以使用CASE表达式。

Try this,

SELECT p_id
    ,SUM(earned) AS total_earned
    ,AVG(desired) AS avg_desired
    ,COUNT(CASE WHEN Earned!=0 THEN 1 END) AS earned_count
    ,SUM(desired) AS sum_desired
FROM table
GROUP BY p_id;

#2


3  

A shorter alternative to CASE is

CASE的一个较短的替代品是

SELECT p_id,
    SUM(earned) AS total_earned,
    AVG(desired) AS average_desired,
    COUNT(earned != 0 OR NULL) AS earned_count,
    SUM(desired) AS sum_desired
FROM table GROUP BY p_id;

because NULLs are not counted.

因为NULL不计算在内。

#3


3  

You have almost done your query just add conditional aggregation with help of case expression for earned count

您几乎完成了查询,只需添加条件聚合,并在案例表达式的帮助下为获得的计数添加

SELECT 
           p_id,
           SUM(earned) [total_earned],
           AVG(desired) [desired],
           SUM(CASE WHEN earned <> 0 THEN 1 ELSE 0 END) [COUNT],
           SUM(desired) [SUM] FROM <table>
 GROUP BY p_id

Result

p_id    total_earned  desired   COUNT  SUM
1       7             10        1      30
2       9             2         3      6

#4


1  

NULLIF() is standard SQL and probably shortest:

NULLIF()是标准SQL,可能是最短的:

SELECT p_id
     , count(NULLIF(earned, 0)) AS earned_count
  -- , more ...
FROM   table
GROUP  BY 1;

count() only counts non-null values.

count()仅计算非空值。

More variants: