我有来自sql server的数据:
select * from log
我想要做的是检查列名的代码是否有任何变化。因此,如果您看到表日志中的数据,则代码会更改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
得到这样的结果。
但是,我不希望检索第一行。因为它是第一个值,我不需要它。所以我只想通过列代码检索更改。如果你知道怎么做,请帮忙。
请注意,我无法使用过滤器where code <> 'B01'
编写查询,因为在这种情况下,我不知道第一个值是什么。
请假设第一个值是首先插入表中的数据。
答案 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。