Lets say you have table Table1
with following columns: | A | B | C | D |
| A | B | C | D |
and you need to produce following result set via SELECT and GROUP BY D statement
| X1 | X2 | X3 | X4 | X5 | X6 |
where those columns are defined as:
X1 = sum(A) if C = 0 OR 12
X2 = sum(B) if C = 0 OR 12
X3 = sum(A) if C = 2
X4 = sum(B) if C = 2
X5 = sum(A) if C = 1
X6 = sum(B) if C = 1
Values for column C
goes from 0, 1, 2, 3, ..., 12
.
One approach would be to use subquery
for each calculation such as:
SELECT
(
SELECT COALESCE(SUM(A), 0.00)
FROM Table1
WHERE C = 0 OR C = 12
) AS 'X1',
(
SELECT COALESCE(SUM(B), 0.00)
FROM Table1
WHERE C = 0 OR C = 12
) AS 'X2',
(
SELECT COALESCE(SUM(A), 0.00)
FROM Table1
WHERE C = 2
) AS 'X3',
(
SELECT COALESCE(SUM(B), 0.00)
FROM Table1
WHERE C = 2
) AS 'X4',
(
SELECT COALESCE(SUM(A), 0.00)
FROM Table1
WHERE C = 1
) AS 'X5',
(
SELECT COALESCE(SUM(B), 0.00)
FROM Table1
WHERE C = 1
) AS 'X6'
FROM Table 1
WHERE C IN (0, 1, 2, 12)
GROUP BY D
Performance wise, to me seems like a brute-force. Probably same thing could be converted using CASE
instead subqueries
, but i doubt it would affect performance in positive way? or it should? Any other/better approach(es) in mind? As an general question how number of subqueries affects performance?
Use conditional aggregation:
select d,
sum(case when c in (0, 12) then a else 0 end) as x1,
sum(case when c in (0, 12) then b else 0 end) as x2,
sum(case when c = 2 then a else 0 end) as x3,
. . .
from t
group by d;
This should definitely be faster than subqueries.
Gordon beat me to the answer. This can be done with pretty standard SQL.
MySQL 5.6 Schema Setup :
CREATE TABLE t1 (a int, b int, c int, d int) ;
INSERT INTO t1 (a,b,c,d)
SELECT 1,1,0,10 UNION ALL
SELECT 1,1,0,10 UNION ALL
SELECT 1,1,0,20 UNION ALL
SELECT 1,1,0,20 UNION ALL
SELECT 1,1,1,10 UNION ALL
SELECT 1,1,1,20 UNION ALL
SELECT 1,1,2,10 UNION ALL
SELECT 1,1,2,30 UNION ALL
SELECT 1,1,3,10 UNION ALL
SELECT 1,1,5,10 UNION ALL
SELECT 1,1,12,10 UNION ALL
SELECT 1,1,5,10 UNION ALL
SELECT 1,1,5,10 UNION ALL
SELECT 1,1,5,20 UNION ALL
SELECT 1,1,5,20
Query 1 :
SELECT d
, sum(CASE WHEN c IN (0,12) THEN a ELSE 0 END) AS x1
, sum(CASE WHEN c IN (0,12) THEN b ELSE 0 END) AS x2
, sum(CASE WHEN c = 2 THEN a ELSE 0 END) AS x3
, sum(CASE WHEN c = 2 THEN b ELSE 0 END) AS x4
, sum(CASE WHEN c = 1 THEN a ELSE 0 END) AS x5
, sum(CASE WHEN c = 1 THEN b ELSE 0 END) AS x6
FROM t1
WHERE c IN (0,1,2,12)
GROUP BY d
Results :
| d | x1 | x2 | x3 | x4 | x5 | x6 |
|----|----|----|----|----|----|----|
| 10 | 3 | 3 | 1 | 1 | 1 | 1 |
| 20 | 2 | 2 | 0 | 0 | 1 | 1 |
| 30 | 0 | 0 | 1 | 1 | 0 | 0 |
If you have a lot of values in c
that aren't in 0,1,2,12
, then you can use the WHERE
to pare down the result set you'll be aggregating. Otherwise, you can probably remove it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.