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 NULL
s 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:
- For absolute performance, is SUM faster or COUNT?
对于绝对性能,SUM更快还是COUNT?
#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 NULL
s 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:
- For absolute performance, is SUM faster or COUNT?
对于绝对性能,SUM更快还是COUNT?