SQL : Return 列值基于前几行值
SQL : Return column value based on previous few rows values
我有一个 table 像这样的东西
NAME TIME IsTrue
A 15-05-2015 02:00 0
B 15-05-2015 03:00 1
C 15-05-2015 06:00 0
D 15-05-2015 13:00 0
E 15-05-2015 23:00 0
F 16-05-2015 04:00 0
E 16-05-2015 07:00 1
G 16-05-2015 23:00 0
我正在尝试编写一个查询,其输出应该是这样的
NAME TIME IsTrue
A 15-05-2015 02:00 0
B 15-05-2015 03:00 1
C 15-05-2015 06:00 1
D 15-05-2015 13:00 1
E 15-05-2015 23:00 1
F 16-05-2015 04:00 0
E 16-05-2015 07:00 1
G 16-05-2015 23:00 1
这里可以观察到IsTrue
的值是在过去24小时内任意一行的值为1
的条件下设置的。
我不想更改 table 本身,只想更改 return 值。
有人可以帮忙吗?
提前致谢,
问候,Ganesh。
P.S。如果重要的话,我正在使用 Microsoft SQL 服务器。
试试这个
with cte as
(
Select Row_Number() over(Partition by convert(date,Time) order by Time)as Rno,Name,Istrue,time from test
)
select Rno,Name,Time,Case when Rno>1 then 1 else 0 end as Istrue from cte
请检查工作 DEMO
这是最简单但性能方面次优的解决方案。它使用相关的子查询来计算每一行:
SELECT
[NAME]
, [TIME]
, (SELECT MAX(IsTrue+0) FROM TABLE1 it WHERE DATEADD(DD,1,it.TIME) > ot.TIME AND it.TIME <= ot.Time) [ISTRUE]
FROM Table1 ot
我不知道你有多少数据。它可以很好地处理这个示例,但如果您有数百万行,我们可能需要寻找更好的东西。
注意 MAX(IsTrue) 中的 +0 以启用在位列上使用聚合函数
你可以这样写:
-- now get all records with desired results
SELECT DISTINCT T3.NAME
,T3.[Time]
,case when T4.NAME IS NULL THEN 0 ELSE 1 END AS IsTrue
FROM @Test T3
LEFT JOIN
(
-- get all rows for which Istrue condition holds true
SELECT T1.NAME,T1.[Time]
FROM @Test T1
WHERE EXISTS ( SELECT IsTrue
FROM @Test T2
WHERE DATEDIFF (hh,T2.Time,T1.Time) BETWEEN 0 AND 24 AND T2.IsTrue = 1)
) T4 ON T3.NAME = T4.NAME AND T3.[Time] = T4.[Time]
ORDER BY T3.[Time]
我有一个 table 像这样的东西
NAME TIME IsTrue
A 15-05-2015 02:00 0
B 15-05-2015 03:00 1
C 15-05-2015 06:00 0
D 15-05-2015 13:00 0
E 15-05-2015 23:00 0
F 16-05-2015 04:00 0
E 16-05-2015 07:00 1
G 16-05-2015 23:00 0
我正在尝试编写一个查询,其输出应该是这样的
NAME TIME IsTrue
A 15-05-2015 02:00 0
B 15-05-2015 03:00 1
C 15-05-2015 06:00 1
D 15-05-2015 13:00 1
E 15-05-2015 23:00 1
F 16-05-2015 04:00 0
E 16-05-2015 07:00 1
G 16-05-2015 23:00 1
这里可以观察到IsTrue
的值是在过去24小时内任意一行的值为1
的条件下设置的。
我不想更改 table 本身,只想更改 return 值。 有人可以帮忙吗?
提前致谢,
问候,Ganesh。
P.S。如果重要的话,我正在使用 Microsoft SQL 服务器。
试试这个
with cte as
(
Select Row_Number() over(Partition by convert(date,Time) order by Time)as Rno,Name,Istrue,time from test
)
select Rno,Name,Time,Case when Rno>1 then 1 else 0 end as Istrue from cte
请检查工作 DEMO
这是最简单但性能方面次优的解决方案。它使用相关的子查询来计算每一行:
SELECT
[NAME]
, [TIME]
, (SELECT MAX(IsTrue+0) FROM TABLE1 it WHERE DATEADD(DD,1,it.TIME) > ot.TIME AND it.TIME <= ot.Time) [ISTRUE]
FROM Table1 ot
我不知道你有多少数据。它可以很好地处理这个示例,但如果您有数百万行,我们可能需要寻找更好的东西。
注意 MAX(IsTrue) 中的 +0 以启用在位列上使用聚合函数
你可以这样写:
-- now get all records with desired results
SELECT DISTINCT T3.NAME
,T3.[Time]
,case when T4.NAME IS NULL THEN 0 ELSE 1 END AS IsTrue
FROM @Test T3
LEFT JOIN
(
-- get all rows for which Istrue condition holds true
SELECT T1.NAME,T1.[Time]
FROM @Test T1
WHERE EXISTS ( SELECT IsTrue
FROM @Test T2
WHERE DATEDIFF (hh,T2.Time,T1.Time) BETWEEN 0 AND 24 AND T2.IsTrue = 1)
) T4 ON T3.NAME = T4.NAME AND T3.[Time] = T4.[Time]
ORDER BY T3.[Time]