SQL检测行中的更改

时间:2017-09-08 13:19:37

标签: sql sql-server partition

我有来自sql server的数据:

select * from log

data

我想要做的是检查列名的代码是否有任何变化。因此,如果您看到表日志中的数据,则代码会更改2次(B02,B03)。

我想要做的是我想要检索每次代码更改时第一次更改的行。在此示例中,第一个更改位于红色框中。所以我想得到第5行和第9行的结果。

我尝试使用下面的分区代码:

select a.name,a.code from(
select name,code,row_number() over(partition by code order by name) as rank from log)a
where a.rank=1

得到这样的结果。

result

但是,我不希望检索第一行。因为它是第一个值,我不需要它。所以我只想通过列代码检索更改。如果你知道怎么做,请帮忙。

请注意,我无法使用过滤器where code <> 'B01'编写查询,因为在这种情况下,我不知道第一个值是什么。

请假设第一个值是首先插入表中的数据。

3 个答案:

答案 0 :(得分:1)

使用lag获取上一行的值(假设id指定排序)并获取与当前行的值不同的行。

select name,code
from (select l.*,lag(code) over(partition by name order by id) as prev_code
      from log
     ) l
where prev_code <> code

答案 1 :(得分:1)

create table #log (name nvarchar(100), code nvarchar(100));

insert into #log values ('SARUMA','B01'), ('SARUMA','B01'), ('SARUMA','B01'), ('SARUMA','B01');
insert into #log values ('SARUMA','B02'), ('SARUMA','B02'), ('SARUMA','B02'), ('SARUMA','B02');
insert into #log values ('SARUMA','B03'), ('SARUMA','B03');

-- remove duplicates
with Singles (name, code) 
AS (
select distinct name, code from #log
),
-- at first you need an order, in time? by alphanumerical code? otherwise you cannot decide wich is the first item you want to remove
-- so i added an identity ordering, but is prefereable a phisical column
OrderedSingles (name, code, id) 
AS (
select *, row_number() over(order by name)
from Singles
)
-- now self-join to get the next one, if the index is sequential you can join id = id+1
-- and take the join columns
select distinct ii.name, ii.Code
from OrderedSingles i
inner join OrderedSingles ii 
    on i.Name = ii.Name and i.Code <> ii.Code
where i.id < ii.Id;

答案 2 :(得分:0)

我认为您的原始帖子非常接近,但您希望窗口函数位于[NAME]列,而不是代码。请参阅下面的修改。我还将谓词更改为>1,因为1将是原始记录。

SELECT 
    a.[name]
   ,a.[code] 
FROM (
    SELECT 
        [name]
       ,[code]
       ,ROW_NUMBER() OVER(PARTITION BY [name] order by [name], [code]) AS [rank] 
    FROM log)a
WHERE a.rank>1

注意:您可能不希望将NAME用作字段,因为它是保留字。此外,RANK也是一个保留字,您已经使用它来对嵌套查询中的ROW_NUMBER进行别名。您可能想要使用另一个非保留字 - 就我个人而言,我为此目的使用RANKED。