我有这张桌子:
Timestamp[DateTime] | Code [Text]
01-jan-2010 00:00:00 | ABC
01-jan-2010 02:00:00 | AAA
01-jan-2010 02:20:00 |
01-jan-2010 03:00:00 | BBB
我希望根据Code != ''
表示RUNNING
的信息以及其他所有内容STOPPED
的信息,按开始和停止时间对条目进行分组。
结果看起来像这样(在找到RUNNING
之前不重复STOPPED
条目)
Timestamp[DateTime] | Status [Text]
01-jan-2010 00:00:00 | RUNNING
01-jan-2010 02:20:00 | STOPPED
01-jan-2010 03:00:00 | RUNNING
我尝试在一个查询中选择这两种类型,但我不认为这是正确的,因为两个子查询中的列名相同,并且它不会对RUNNING条目进行分组。实现这一结果的最佳方法是什么?我相信目前的方法对我没有多大帮助,所以欢迎任何想法。
标准SQL语法最好。 SQL Server Express也是一个选项。
当前尝试:
SELECT Timestamp, Status
FROM (SELECT Timestamp, 'RUNNING' as Status FROM MyTable WHERE Code != ''),
(SELECT Timestamp, 'STOPPED' as Status FROM MyTable WHERE Code = '')
答案 0 :(得分:2)
这是一个带有扭曲的空白和岛屿问题:
select "timestamp",
case
when code is null then 'running'
else 'stopped'
end as status
from (
select "timestamp", code,
lag(code) over (order by timestamp) as prev_code
from mytable
) as t
where prev_code is null or code is null
以上是标准的ANSI SQL。
请注意,我必须将timestamp
放在引号中,因为这是标准SQL中的保留字。我也在检查null
而不是code
列中的空字符串。
以下是给出样本数据的运行示例:
答案 1 :(得分:1)
SELECT
r.Timestamp
,CASE WHEN r.T1Code != '' THEN 'RUNNING' ELSE 'STOPPED' END as Status
FROM
(
SELECT
t1.Timestamp
,CAST(COALESCE(t1.Code,'') AS VARCHAR(MAX)) as T1Code
,(SELECT TOP 1 CAST(COALESCE(t2.Code,'') AS VARCHAR(MAX))
FROM
myTable t2
WHERE
t2.Timestamp < t1.Timestamp
ORDER BY
t2.Timestamp DESC) as T2Code
FROM
myTable t1
) r
WHERE
NOT(r.T1Code != '' AND r.T2Code != '')
OR r.T2Code IS NULL
更新为允许测试Null或Empty字符串,并考虑文本数据类型的比较问题。
http://rextester.com/OBWS90094显示效果
如果您真的想要在Code不为null或为空时停止/运行的相反含义,请更改以下行:
CASE WHEN r.T1Code = '' THEN 'RUNNING' ELSE 'STOPPED' END as Status
AND
WHERE
NOT(r.T1Code = '' AND r.T2Code = '')
OR r.T2Code IS NULL
这表明它有效:http://rextester.com/KUGW22706
您实际上可以在一个查询中完成所有操作,但在嵌套查询中显示逻辑会更容易,以便我可以使用列引用。如果您的DBMS支持诸如横向连接/应用和/或LAG / LEAD窗口函数之类的东西,那么它会更简单一些,但您可以使用Column定义中的相关子查询来执行相同的操作。该子查询获取前一个Timestamp Row的代码。如果当前行代码和前一行代码都是!=&#39;&#39;然后它仍在运行,所以不要显示记录。但是你仍然需要包含第一条记录,所以测试t2.Code是否为空。
答案 2 :(得分:1)
select [Timestamp],[status]
from
(
select [Timestamp]
, lag(Code,1,'') over ( order by [Timestamp] ) lead
,code
,iif(Code ='','STOPPED','RUNNING') [status]
from [Table]) x
where lead = '' or code =''
答案 3 :(得分:1)