FLI*_*KER 17 t-sql sql-server aggregation sql-server-2012
我在桌子下面
create table #t (Id int, Name char)
insert into #t values
(1, 'A'),
(2, 'A'),
(3, 'B'),
(4, 'B'),
(5, 'B'),
(6, 'B'),
(7, 'C'),
(8, 'B'),
(9, 'B')
Run Code Online (Sandbox Code Playgroud)
我想在name列中计算连续值
+------+------------+
| Name | Repetition |
+------+------------+
| A | 2 |
| B | 4 |
| C | 1 |
| B | 2 |
+------+------------+
Run Code Online (Sandbox Code Playgroud)
我尝试过的最好的事情是:
select Name
, COUNT(*) over (partition by Name order by Id) AS Repetition
from #t
order by Id
Run Code Online (Sandbox Code Playgroud)
但它没有给我预期的结果
Gor*_*off 22
一种方法是行数的差异:
select name, count(*)
from (select t.*,
(row_number() over (order by id) -
row_number() over (partition by name order by id)
) as grp
from t
) t
group by grp, name;
Run Code Online (Sandbox Code Playgroud)
如果运行子查询并分别查看每个行号的值,那么逻辑最容易理解,然后查看差异.
您可以使用窗口函数,例如LAG
和 running total:
WITH cte AS (
SELECT Id, Name, grp = SUM(CASE WHEN Name = prev THEN 0 ELSE 1 END) OVER(ORDER BY id)
FROM (SELECT *, prev = LAG(Name) OVER(ORDER BY id) FROM t) s
)
SELECT name, cnt = COUNT(*)
FROM cte
GROUP BY grp,name
ORDER BY grp;
Run Code Online (Sandbox Code Playgroud)
第一个 cte 返回组号:
+-----+-------+-----+
| Id | Name | grp |
+-----+-------+-----+
| 1 | A | 1 |
| 2 | A | 1 |
| 3 | B | 2 |
| 4 | B | 2 |
| 5 | B | 2 |
| 6 | B | 2 |
| 7 | C | 3 |
| 8 | B | 4 |
| 9 | B | 4 |
+-----+-------+-----+
Run Code Online (Sandbox Code Playgroud)
主查询根据grp
之前计算的列对其进行分组:
+-------+-----+
| name | cnt |
+-------+-----+
| A | 2 |
| B | 4 |
| C | 1 |
| B | 2 |
+-------+-----+
Run Code Online (Sandbox Code Playgroud)