Sql server 根据列的顺序跟踪SqlServer中的更改或分组,如Excel中的小计
我有一张这样的桌子:Sql server 根据列的顺序跟踪SqlServer中的更改或分组,如Excel中的小计,sql-server,Sql Server,我有一张这样的桌子: CREATE TABLE dbo.Samples ( Id INT PRIMARY KEY, A INT NOT NULL, B INT NOT NULL, C INT NOT NULL, D
CREATE TABLE dbo.Samples
(
Id INT PRIMARY KEY,
A INT NOT NULL,
B INT NOT NULL,
C INT NOT NULL,
D INT NOT NULL,
)
GO
INSERT INTO dbo.Samples
( Id, A, B, C, D )
SELECT 1, 10, 10, 10, 10 UNION
SELECT 2, 10, 10, 11, 10 UNION
SELECT 3, 11, 10, 11, 10 UNION
SELECT 4, 11, 10, 11, 11 UNION
SELECT 5, 10, 10, 11, 11
1 10 10 10 10
3 11 10 11 10
5 10 10 11 11
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
我正在寻找一个显示和跟踪此表中两列a和B的更改历史的查询。
结果应该是这样的:
CREATE TABLE dbo.Samples
(
Id INT PRIMARY KEY,
A INT NOT NULL,
B INT NOT NULL,
C INT NOT NULL,
D INT NOT NULL,
)
GO
INSERT INTO dbo.Samples
( Id, A, B, C, D )
SELECT 1, 10, 10, 10, 10 UNION
SELECT 2, 10, 10, 11, 10 UNION
SELECT 3, 11, 10, 11, 10 UNION
SELECT 4, 11, 10, 11, 11 UNION
SELECT 5, 10, 10, 11, 11
1 10 10 10 10
3 11 10 11 10
5 10 10 11 11
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
因为在Id为1、3和5的记录中,a列或B列发生了变化。
我对这个问题有一个不完整的解决方案:
WITH cte
AS
(
SELECT TOP 1 1 HasChange, * FROM Samples ORDER BY Id
UNION ALL
SELECT IIF(cte.A != q.A OR cte.B != q.B, 1, 0), q.* FROM Samples q
INNER JOIN cte ON cte.Id + 1 = q.Id
)
SELECT Id, A,B,C,D FROM cte WHERE HasChange = 1
但我想知道在SQLServer中是否有更好更简单的解决方案。
此外,当我使用大数据测试此查询时,会收到如下错误消息:
CREATE TABLE dbo.Samples
(
Id INT PRIMARY KEY,
A INT NOT NULL,
B INT NOT NULL,
C INT NOT NULL,
D INT NOT NULL,
)
GO
INSERT INTO dbo.Samples
( Id, A, B, C, D )
SELECT 1, 10, 10, 10, 10 UNION
SELECT 2, 10, 10, 11, 10 UNION
SELECT 3, 11, 10, 11, 10 UNION
SELECT 4, 11, 10, 11, 11 UNION
SELECT 5, 10, 10, 11, 11
1 10 10 10 10
3 11 10 11 10
5 10 10 11 11
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
我的问题是:
Select *
From (
Select *
,Flg = case when concat([A],[B])=lag(concat([A],[B]),1,'') over (Order by ID) then 0 else 1 end
From Samples
) A
Where Flg=1
返回
一个选项是使用lag()
示例
Select *
From (
Select *
,Flg = case when concat([A],[B])=lag(concat([A],[B]),1,'') over (Order by ID) then 0 else 1 end
From Samples
) A
Where Flg=1
返回
非常感谢,我不知道sqlserver中的滞后功能。这是非常有用的,似乎是一个完整和完美的解决方案,这个问题。thanks@JafarElahi很乐意帮忙。窗口功能是非常宝贵的。非常值得您花时间熟悉它们:)非常感谢,我不知道sqlserver中的滞后函数。这是非常有用的,似乎是一个完整和完美的解决方案,这个问题。thanks@JafarElahi很乐意帮忙。窗口功能是非常宝贵的。值得你花时间去适应它们:)