SQL DENSE_RANK 不是 suitable 因为存在 table- 如何在 val 更改时按顺序获取 min/max 日期
SQL DENSE_RANK not suitable because of existing table- how to get min/max dates in sequence when val changes
我有一个现有的@table
ID Date Val
1 2014-10-01 1
2 2014-10-02 1
3 2014-10-03 1
4 2014-10-04 1
5 2014-10-05 1
6 2014-10-06 1
7 2014-10-07 1
8 2014-10-08 1
9 2014-10-09 1
日期顺序很重要。
我需要查看每个 Val 序列的第一个和最后一个日期:
Select Val,MIN([Date]) as A, MAX([Date]) as B
from @T
Group by Val
Val From To
1 2014-10-01 2014-10-09
Val 列现在更改了其中 3 个条目:
Update @T set Val = 2 where [ID] between 3 and 5
和returns:
ID Date Val
1 2014-10-01 1
2 2014-10-02 1
3 2014-10-03 2
4 2014-10-04 2
5 2014-10-05 2
6 2014-10-06 1
7 2014-10-07 1
8 2014-10-08 1
9 2014-10-09 1
如何获取每个序列的 SQL 到 return min/max 日期?
我需要展示 :
即
1 2014-10-01 2014-10-02
2 2014-10-03 2014-10-05
1 2014-10-06 2014-10-09
如果我 运行 正常 Min/Max 查询,我得到
1 2014-10-01 2014-10-09
2 2014-10-03 2014-10-05
这并没有告诉我第一期的 val 是 1,第二期是 2
第三节又是 1
declare @T table(ID int,[Date] date,Val int)
Insert Into @T(ID,[Date],Val)
values(1,'2014/10/01', 1),
(2,'2014/10/02', 1),
(3,'2014/10/03', 1),
(4,'2014/10/04', 1),
(5,'2014/10/05', 1),
(6,'2014/10/06', 1),
(7,'2014/10/07', 1),
(8,'2014/10/08', 1),
(9,'2014/10/09', 1)
试试这个
SELECT Val,Min(Date) Min_Date,Max(Date) Max_Date
FROM
(
SELECT ID,Date,Val,SUM(NewVal) OVER (order by ID) AS NewVal
FROM
(
SELECT ID,Date,Val,CASE WHEN Val<>LAG(Val, 1) OVER (ORDER BY ID) THEN 1 ELSE 0 END NewVal
FROM @T
) I
) O
GROUP BY NewVal,Val
ORDER BY Min_Date
我采用了之前对我自己的一个问题的回答
基本上您是在使用 LAG 函数比较上一行的值。如果它不同,则将其设置为 1,否则使用 0。然后将其包装在 运行 总和中,每次 NewVal 增加 1 时该总和只会递增。查询结果与您要查找的结果相匹配。
记录的顺序显然对这个答案非常重要。因此,根据您的具体需求,您可能需要调整 OVER 子句。
编辑
根据评论,这是一个不使用 LAG 的替代答案,因此它适用于 SQL Server 2008。
SELECT Val,Min(Date) Min_Date,Max(Date) Max_Date
FROM
(
SELECT ID,Date,Val,SUM(NewVal) OVER (order by ID) AS NewVal
FROM
(
SELECT M.ID,M.Date,M.Val,CASE WHEN M.Val<>L.Val THEN 1 ELSE 0 END NewVal
FROM @T M
LEFT JOIN
(
SELECT ID,Date,Val,ROW_NUMBER() OVER(order by ID)+1 NewRowId
FROM @T
) L ON M.ID=L.NewRowId
) I
) O
GROUP BY NewVal,Val
ORDER BY Min_Date
我有一个现有的@table
ID Date Val
1 2014-10-01 1
2 2014-10-02 1
3 2014-10-03 1
4 2014-10-04 1
5 2014-10-05 1
6 2014-10-06 1
7 2014-10-07 1
8 2014-10-08 1
9 2014-10-09 1
日期顺序很重要。 我需要查看每个 Val 序列的第一个和最后一个日期:
Select Val,MIN([Date]) as A, MAX([Date]) as B
from @T
Group by Val
Val From To
1 2014-10-01 2014-10-09
Val 列现在更改了其中 3 个条目:
Update @T set Val = 2 where [ID] between 3 and 5
和returns:
ID Date Val
1 2014-10-01 1
2 2014-10-02 1
3 2014-10-03 2
4 2014-10-04 2
5 2014-10-05 2
6 2014-10-06 1
7 2014-10-07 1
8 2014-10-08 1
9 2014-10-09 1
如何获取每个序列的 SQL 到 return min/max 日期?
我需要展示 :
即
1 2014-10-01 2014-10-02
2 2014-10-03 2014-10-05
1 2014-10-06 2014-10-09
如果我 运行 正常 Min/Max 查询,我得到
1 2014-10-01 2014-10-09
2 2014-10-03 2014-10-05
这并没有告诉我第一期的 val 是 1,第二期是 2 第三节又是 1
declare @T table(ID int,[Date] date,Val int)
Insert Into @T(ID,[Date],Val)
values(1,'2014/10/01', 1),
(2,'2014/10/02', 1),
(3,'2014/10/03', 1),
(4,'2014/10/04', 1),
(5,'2014/10/05', 1),
(6,'2014/10/06', 1),
(7,'2014/10/07', 1),
(8,'2014/10/08', 1),
(9,'2014/10/09', 1)
试试这个
SELECT Val,Min(Date) Min_Date,Max(Date) Max_Date
FROM
(
SELECT ID,Date,Val,SUM(NewVal) OVER (order by ID) AS NewVal
FROM
(
SELECT ID,Date,Val,CASE WHEN Val<>LAG(Val, 1) OVER (ORDER BY ID) THEN 1 ELSE 0 END NewVal
FROM @T
) I
) O
GROUP BY NewVal,Val
ORDER BY Min_Date
我采用了之前对我自己的一个问题的回答
基本上您是在使用 LAG 函数比较上一行的值。如果它不同,则将其设置为 1,否则使用 0。然后将其包装在 运行 总和中,每次 NewVal 增加 1 时该总和只会递增。查询结果与您要查找的结果相匹配。
记录的顺序显然对这个答案非常重要。因此,根据您的具体需求,您可能需要调整 OVER 子句。
编辑
根据评论,这是一个不使用 LAG 的替代答案,因此它适用于 SQL Server 2008。
SELECT Val,Min(Date) Min_Date,Max(Date) Max_Date
FROM
(
SELECT ID,Date,Val,SUM(NewVal) OVER (order by ID) AS NewVal
FROM
(
SELECT M.ID,M.Date,M.Val,CASE WHEN M.Val<>L.Val THEN 1 ELSE 0 END NewVal
FROM @T M
LEFT JOIN
(
SELECT ID,Date,Val,ROW_NUMBER() OVER(order by ID)+1 NewRowId
FROM @T
) L ON M.ID=L.NewRowId
) I
) O
GROUP BY NewVal,Val
ORDER BY Min_Date