Sql 服务器 - 根据条件汇总的行
Sql Server - Rows Summing Up Based on Conditions
我正在使用 Sql 服务器,我必须减少一些有条件的行,并将小时字段求和到一个新行中。
条件是这样的
如果 ID1 ==(1 或 2)且 ID2 和 YEAR 相同,则应在 ID1 = 4 的新行中汇总小时数
ID1
ID2
YEAR
HOUR
1
2441
2021
4,03
2
2441
2021
NULL
1
2468
2021
30
2
2468
2021
31,21
3
2441
2021
145,99
结果
ID1
ID2
YEAR
HOUR
4
2441
2021
4,03
4
2468
2021
61,21
3
2441
2021
145,99
我该怎么做?
您可以使用 case
表达式。为避免重复,我建议使用 values()
:
select v.id1, t.id2, t.year, sum(t.hour)
from t cross apply
(values (case when id1 in (1, 2) then 4 else id1 end)
) v(id1)
group by v.id1, t.id2, t.year;
注意:这会将具有相同 id1
/id2
/year
的其他行合并为一行。如果你不想要这个,那么你需要一个原始的唯一id table。你可以用:
select v.id1, t.id2, t.year, sum(t.hour)
from (select t.*,
row_number() over (order by (select null)) as seqnum
from t
) t cross apply
(values (case when id1 in (1, 2) then 4 else id1 end)
) v(id1)
group by v.id1, t.id2, t.year,
(case when id1 <> 4 then seqnum end);
你似乎想要 GROUP BY
ID2
和 YEAR
SELECT ID1 = (SELECT MAX(ID1) FROM tbl) + 1,
ID2,
[YEAR],
[HOUR] = SUM ([HOUR] )
FROM tbl
WHERE ID1 IN (1, 2)
GROUP BY ID2, [YEAR]
UNION ALL
SELECT ID1, ID2, [YEAR], [HOUR]
FROM tbl
WHERE ID1 NOT IN (1, 2)
如果 ID2 和 YEAR 与上面类似,一种方法是简单地用 case(或 IF)更改 ID1 并用 GROUP BY
求和
SELECT CASE WHEN ID1 IN (1,2) THEN 4
ELSE ID1
END
,AVG(ID2)
,AVG(YEAR)
,SUM(HOUR)
FROM Table1
GROUP BY CASE WHEN ID1 IN (1,2) THEN 4
ELSE ID1
END
我正在使用 Sql 服务器,我必须减少一些有条件的行,并将小时字段求和到一个新行中。
条件是这样的
如果 ID1 ==(1 或 2)且 ID2 和 YEAR 相同,则应在 ID1 = 4 的新行中汇总小时数
ID1 | ID2 | YEAR | HOUR |
---|---|---|---|
1 | 2441 | 2021 | 4,03 |
2 | 2441 | 2021 | NULL |
1 | 2468 | 2021 | 30 |
2 | 2468 | 2021 | 31,21 |
3 | 2441 | 2021 | 145,99 |
结果
ID1 | ID2 | YEAR | HOUR |
---|---|---|---|
4 | 2441 | 2021 | 4,03 |
4 | 2468 | 2021 | 61,21 |
3 | 2441 | 2021 | 145,99 |
我该怎么做?
您可以使用 case
表达式。为避免重复,我建议使用 values()
:
select v.id1, t.id2, t.year, sum(t.hour)
from t cross apply
(values (case when id1 in (1, 2) then 4 else id1 end)
) v(id1)
group by v.id1, t.id2, t.year;
注意:这会将具有相同 id1
/id2
/year
的其他行合并为一行。如果你不想要这个,那么你需要一个原始的唯一id table。你可以用:
select v.id1, t.id2, t.year, sum(t.hour)
from (select t.*,
row_number() over (order by (select null)) as seqnum
from t
) t cross apply
(values (case when id1 in (1, 2) then 4 else id1 end)
) v(id1)
group by v.id1, t.id2, t.year,
(case when id1 <> 4 then seqnum end);
你似乎想要 GROUP BY
ID2
和 YEAR
SELECT ID1 = (SELECT MAX(ID1) FROM tbl) + 1,
ID2,
[YEAR],
[HOUR] = SUM ([HOUR] )
FROM tbl
WHERE ID1 IN (1, 2)
GROUP BY ID2, [YEAR]
UNION ALL
SELECT ID1, ID2, [YEAR], [HOUR]
FROM tbl
WHERE ID1 NOT IN (1, 2)
如果 ID2 和 YEAR 与上面类似,一种方法是简单地用 case(或 IF)更改 ID1 并用 GROUP BY
求和SELECT CASE WHEN ID1 IN (1,2) THEN 4
ELSE ID1
END
,AVG(ID2)
,AVG(YEAR)
,SUM(HOUR)
FROM Table1
GROUP BY CASE WHEN ID1 IN (1,2) THEN 4
ELSE ID1
END