在 T-SQL 中的连续行中适当设置计数器
Setting a counter appropriately in sequentially rows in T-SQL
我有两个问题。
问题一:
我有 table 个具有架构的值:
CREATE TABLE Numbers (Id int, Column1 int);
让我们假设以下数据:
INSERT INTO Numbers (Id int, Column1)
VALUES
(1, 1),
(2, 0),
(3, 0),
(4, 0),
(5, 1),
(6, 1),
(7, 1),
(8, 0),
(9, 1),
(10, 1),
(11, 0),
(12, 1);
我想要的是一个 T-SQL 查询来生成以下数据作为所需的输出:
Id, Column1, GroupID
(1, 1, 1)
(2, 0, 2)
(3, 0, 3)
(4, 0, 4)
(5, 1, 5)
(6, 1, 5)
(7, 1, 5)
(8, 0, 6)
(9, 1, 7)
(10, 1, 7)
(11, 0, 8)
(12, 1, 9)
每当连续的 1 存在时,计数器就是 repeated/copied。
问题二:
我有 table 个具有架构的值:
CREATE TABLE Numbers (Id int, Column1 int, Column2 int);
让我们假设以下数据:
INSERT INTO Numbers (Column1, Column2)
VALUES
(1, 1, 1),
(2, 1, 0),
(3, 1, 0),
(4, 1, 0),
(5, 1, 1),
(6, 1, 1),
(7, 1, 1),
(8, 1, 0),
(9, 1, 1),
(10, 1, 1),
(11, 1, 0),
(12, 1, 1),
(13, 1),
(14, 0),
(15, 0),
(16, 0),
(17, 1),
(18, 1),
(19, 1),
(20, 0),
(21, 1),
(22, 1),
(23, 0),
(24, 1);
我想要的是一个 T-SQL 查询来生成以下数据作为所需的输出:
Id, Column1, Column2, GroupID
(1, 1, 1, 1)
(2, 1, 0, 2)
(3, 1, 0, 3)
(4, 1, 0, 4)
(5, 1, 1, 5)
(6, 1, 1, 5)
(7, 1, 1, 5)
(8, 1, 0, 6)
(9, 1, 1, 7)
(10, 1, 1, 7)
(11, 1, 0, 8)
(12, 1, 1, 9)
(13, 2, 1, 1)
(14, 2, 0, 2)
(15, 2, 0, 3)
(16, 2, 0, 4)
(17, 2, 1, 5)
(18, 2, 1, 5)
(19, 2, 1, 5)
(20, 2, 0, 6)
(21, 2, 1, 7)
(22, 2, 1, 7)
(23, 2, 0, 8)
(24, 2, 1, 9)
只要存在连续的 1,计数器就是 repeated/copied。但是,每当 Column1 的新值到达时,计数器就会重置。
--
T-SQL 查询需要 运行 在 MS SQL 服务器在 Microsoft Azure SQL 数据仓库。
如果您有一列指定排序。一个使用 lag()
和一个累计和:
select t.*,
sum(case when prev_column is null or prev_column <> column
then 1 else 0
end) over (order by ?)
from (select t.*, lag(column) over (order by ?) as prev_column
from t
) t;
?
用于排序列。
如果条件更改为 or not (column1=1 and prev_column=1)
(等同于 or column1!=1 or prev_column!=1
),Gordon 的查询将起作用。此查询:
select Id,Column1,
sum(case when prev_column is null or column1!=1 or prev_column!=1
then 1 else 0
end) over (order by id) as GroupID
from (select t.*, lag(column1) over (order by id) as prev_column
from @numbers t
) t;
Returns
Id Column1 GroupID
1 1 1
2 0 2
3 0 3
4 0 4
5 1 5
6 1 5
7 1 5
8 0 6
9 1 7
10 1 7
11 0 8
12 1 9
第二个问题对于每个不同的 Column2
值都是一样的。这需要 PARTITION BY column2
:
select Id,Column1,Column2,
sum(case when prev_column is null or column2!=1 or prev_column!=1
then 1 else 0
end) over (partition by column1 order by id) as GroupID
from (select t.*, lag(column2) over (partition by column1 order by id) as prev_column
from @numbers t
) t;
这会产生:
Id Column1 Column2 GroupID
1 1 1 1
2 1 0 2
3 1 0 3
4 1 0 4
5 1 1 5
6 1 1 5
7 1 1 5
8 1 0 6
9 1 1 7
10 1 1 7
11 1 0 8
12 1 1 9
13 2 1 1
14 2 0 2
15 2 0 3
16 2 0 4
17 2 1 5
18 2 1 5
19 2 1 5
20 2 0 6
21 2 1 7
22 2 1 7
23 2 0 8
24 2 1 9
我有两个问题。
问题一:
我有 table 个具有架构的值:
CREATE TABLE Numbers (Id int, Column1 int);
让我们假设以下数据:
INSERT INTO Numbers (Id int, Column1)
VALUES
(1, 1),
(2, 0),
(3, 0),
(4, 0),
(5, 1),
(6, 1),
(7, 1),
(8, 0),
(9, 1),
(10, 1),
(11, 0),
(12, 1);
我想要的是一个 T-SQL 查询来生成以下数据作为所需的输出:
Id, Column1, GroupID
(1, 1, 1)
(2, 0, 2)
(3, 0, 3)
(4, 0, 4)
(5, 1, 5)
(6, 1, 5)
(7, 1, 5)
(8, 0, 6)
(9, 1, 7)
(10, 1, 7)
(11, 0, 8)
(12, 1, 9)
每当连续的 1 存在时,计数器就是 repeated/copied。
问题二:
我有 table 个具有架构的值:
CREATE TABLE Numbers (Id int, Column1 int, Column2 int);
让我们假设以下数据:
INSERT INTO Numbers (Column1, Column2)
VALUES
(1, 1, 1),
(2, 1, 0),
(3, 1, 0),
(4, 1, 0),
(5, 1, 1),
(6, 1, 1),
(7, 1, 1),
(8, 1, 0),
(9, 1, 1),
(10, 1, 1),
(11, 1, 0),
(12, 1, 1),
(13, 1),
(14, 0),
(15, 0),
(16, 0),
(17, 1),
(18, 1),
(19, 1),
(20, 0),
(21, 1),
(22, 1),
(23, 0),
(24, 1);
我想要的是一个 T-SQL 查询来生成以下数据作为所需的输出:
Id, Column1, Column2, GroupID
(1, 1, 1, 1)
(2, 1, 0, 2)
(3, 1, 0, 3)
(4, 1, 0, 4)
(5, 1, 1, 5)
(6, 1, 1, 5)
(7, 1, 1, 5)
(8, 1, 0, 6)
(9, 1, 1, 7)
(10, 1, 1, 7)
(11, 1, 0, 8)
(12, 1, 1, 9)
(13, 2, 1, 1)
(14, 2, 0, 2)
(15, 2, 0, 3)
(16, 2, 0, 4)
(17, 2, 1, 5)
(18, 2, 1, 5)
(19, 2, 1, 5)
(20, 2, 0, 6)
(21, 2, 1, 7)
(22, 2, 1, 7)
(23, 2, 0, 8)
(24, 2, 1, 9)
只要存在连续的 1,计数器就是 repeated/copied。但是,每当 Column1 的新值到达时,计数器就会重置。
--
T-SQL 查询需要 运行 在 MS SQL 服务器在 Microsoft Azure SQL 数据仓库。
如果您有一列指定排序。一个使用 lag()
和一个累计和:
select t.*,
sum(case when prev_column is null or prev_column <> column
then 1 else 0
end) over (order by ?)
from (select t.*, lag(column) over (order by ?) as prev_column
from t
) t;
?
用于排序列。
如果条件更改为 or not (column1=1 and prev_column=1)
(等同于 or column1!=1 or prev_column!=1
),Gordon 的查询将起作用。此查询:
select Id,Column1,
sum(case when prev_column is null or column1!=1 or prev_column!=1
then 1 else 0
end) over (order by id) as GroupID
from (select t.*, lag(column1) over (order by id) as prev_column
from @numbers t
) t;
Returns
Id Column1 GroupID
1 1 1
2 0 2
3 0 3
4 0 4
5 1 5
6 1 5
7 1 5
8 0 6
9 1 7
10 1 7
11 0 8
12 1 9
第二个问题对于每个不同的 Column2
值都是一样的。这需要 PARTITION BY column2
:
select Id,Column1,Column2,
sum(case when prev_column is null or column2!=1 or prev_column!=1
then 1 else 0
end) over (partition by column1 order by id) as GroupID
from (select t.*, lag(column2) over (partition by column1 order by id) as prev_column
from @numbers t
) t;
这会产生:
Id Column1 Column2 GroupID
1 1 1 1
2 1 0 2
3 1 0 3
4 1 0 4
5 1 1 5
6 1 1 5
7 1 1 5
8 1 0 6
9 1 1 7
10 1 1 7
11 1 0 8
12 1 1 9
13 2 1 1
14 2 0 2
15 2 0 3
16 2 0 4
17 2 1 5
18 2 1 5
19 2 1 5
20 2 0 6
21 2 1 7
22 2 1 7
23 2 0 8
24 2 1 9