我的行看起来像这样:
1
0 ----> Change! This row is of interest
1 ----> Change again.
1
1
1
1
1
0 ----> Change.
1 ----> Change.
在新的1之前可能有一百万个零,我只想要更改(标记为Change的行)。这将给我带来约1000万行的结果。我们支持SQLServer和PostGresSQL。它按时间戳列排序。 0表示系统脱机标志,1表示系统处于联机状态。服务会定期报告此信息并为其添加时间戳。
有什么想法吗? 编辑: 还有很多其他列,一个是确定订单的时间戳列。 0表示系统脱机标志,1表示系统处于联机状态。服务会定期报告此信息并为其添加时间戳。
干杯
答案 0 :(得分:3)
行。所以根据评论,我们知道有时间戳列。我们假设这被命名为" event_when",并且0/1列被命名为" status"。
所以,我们可以:
with x as (
select
*,
lag(status) over (order by event_when) is distinct from status as interesting
from table
)
select * from x where interesting;
答案 1 :(得分:2)
如果您有ID,并且它们是连续的,您可以尝试类似:
SELECT table1.* FROM table table1, table table2
WHERE table1.id = table2.id- 1
AND table1.value != table2.value
如果没有看到结构的其余部分,说起来有点难,但在上述情况下,value
是包含0
或1
和id
的列是主键。如果您没有id列,或者它们不是增量列,那么您可能需要指定更复杂的选择器,或者在此处包含更多的架构。
答案 2 :(得分:0)
我们必须知道如何找到前一行,但一般解决方案是(我假设你的行有列Date并且它是唯一的)
select *
from temp as t1
outer apply
(
select top 1 *
from temp as t2
where t2.Date < t1.Date /* or you columns */
order by t2.Date desc /* or you columns */
)
where t2.value <> t1.value
编辑:由于我通常在2008 R2 SQL Server上工作,所以我忘记了LAG和LEAD功能。所以,基于@depesz对PostgreSQL的回答,这里是SQL Server版本:
with CTE_temp as (
select
*,
lag([State]) over (order by [Time]) as State_Previous
from temp
)
select *
from CTE_temp
where State_Previous <> [State]
答案 3 :(得分:-1)
选项#1 :使用MS SQL SERVER 2008
使用时间戳排序,我们可以使用rank()
函数和临时表。也可以使用CTE和表变量。性能是一个棘手的部分,所以我建议测试这三个选项,如果这将在未来重复。我将展示两个例子:
TEMPORARY TABLE(try it in SQLFiddle):
select rank() OVER (ORDER BY order_timestamp) as 'Rank', status into temp1 from temp
select t1.status as status, case when t1.status - t2.status = 0 then 'not changed' else 'changed' end as changed
from temp1 t1, temp1 t2
where t1.Rank = t2.Rank + 1
drop table temp1
CTE(try it in SQLFiddle):
with CTE_temp as (
select rank() OVER (ORDER BY order_timestamp) as 'Rank', *
from temp
)
select t1.status as status, case when t1.status - t2.status = 0 then 'not changed' else 'changed' end as changed
from CTE_temp t1, CTE_temp t2
where t1.Rank = t2.Rank + 1
选项#2 :使用MS SQL SERVER 2012
MS SQL SERVER 2012介绍了lead
和lag
(http://blog.sqlauthority.com/2011/11/15/sql-server-introduction-to-lead-and-lag-analytic-functions-introduced-in-sql-server-2012/)。
在这种情况下,选项#1仍然有效,但您也可以尝试@ RomanPekar的解决方案。
<强>更新强>
基于@ RomanPekar的评论(以及某人的评论),我不得不说临时表可以比CTE和表变量完美地执行,特别是当一大组数据是预期。优化程序可以使用临时表中的统计信息来建立其查询计划,这可以提高性能。
同样,根据OP想要在之后提供数据的使用(可能更多查询),临时表仍然存在,不必执行新查询,并且索引可用于提高这些情况下的性能。
BTW,攻击我的答案并将其转换为CTE或表格变量很容易,所以我建议OP测试这三种情况的性能,如果这是他将来会重复的操作。