SQL Server 在重复项中选择不同的连续行

vh0rcniy  于 2023-01-08  发布在  其他
关注(0)|答案(3)|浏览(110)

我有一个结构如下的表:

create table roster
(
date date not null,
first nvarchar(20) not null,
second nvarchar(20) not null,
third nvarchar(20) not null,
fourth nvarchar(20) not null,
)
go

其中插入了以下数据:

insert into roster values ('2015-06-10 12:45:34', 'e', 'm', 'a', 'r')
insert into roster values ('2015-06-11 12:45:34', 'e', 'v', 'a', 'r')
insert into roster values ('2015-06-12 12:45:34', 'e', 'm', 'a', 'd') 
insert into roster values ('2015-06-13 12:45:34', 'e', 'm', 'a', 'd') *
insert into roster values ('2015-06-14 12:45:34', 'e', 'm', 'a', 'r')
insert into roster values ('2015-06-15 12:45:34', 'e', 'm', 'a', 'r') *
insert into roster values ('2015-06-16 12:45:34', 'z', 'm', 't', 'r')

注:* 表示重复。
如何只选择“第一”、“第二”、“第三”和“第四”的一个唯一连续组合?例如,使用上面插入的数据,所需的输出为:

Date                 First Second Third Fourth
2015-06-10 12:45:34, e     m      a     r
2015-06-11 12:45:34, e     v      a     r
2015-06-12 12:45:34, e     m      a     d
2015-06-14 12:45:34, e     m      a     r
2015-06-16 12:45:34, z     m      t     r

我正在寻找一个解决方案,保留条目时,他们不再连续(或当序列被打破),但删除重复的连续条目。
我已经看到类似的问题张贴在这里,但我一直无法作出一个解决方案,使用一组由。
任何帮助都将不胜感激

lb3vh1jj

lb3vh1jj1#

如果您只需要一个exists(),为什么还需要group by呢?

;with data as
(
    select ROW_NUMBER() OVER (ORDER BY date) AS number, * from roster
)
select * from data where 
    not exists -- Just compare with the previous column, if match say bye
    (
        select * from data prev where 1 = 1
            and prev.first = data.first 
            and prev.second = data.second 
            and prev.third = data.third 
            and prev.fourth = data.fourth 
            and prev.number + 1 = data.number
    )

SQL小提琴

    • 编辑**
;with data as
(
    select
        ROW_NUMBER() OVER (ORDER BY date) AS number, 
        ROW_NUMBER() OVER (PARTITION BY first, second, third, fourth ORDER BY date) AS part,
        *
    from roster
)
select MIN(date) as startdate, MAX(date) as enddate, COUNT(*) count, first, second, third, fourth
from data group by first, second, third, fourth, number - part
order by number - part

SQL小提琴

wh6knrhe

wh6knrhe2#

您可以按第一个、第二个、第三个、第四个值进行分组,然后选择遇到这些值的第一个日期(min(date))或最后一次出现的日期(max(date))
遇到的最后日期示例:小提琴

SELECT min(date) as startdate ,max(date) as enddate,  first, second, third, fourth 
from roster
GROUP BY first, second, third, fourth

EDIT:编辑之前的质询,以包括开始和结束日期
额外:一些我在玩的时候等待你的答复:包括数值出现在1个字段中的日期列表:

SELECT first, second, third, fourth,
STUFF((
          SELECT ',' + convert(varchar(25),T.date)
          FROM roster T
          WHERE A.first = T.first
          AND A.second = T.second
          AND A.third = T.third
          AND A.fourth = T.fourth
          ORDER BY T.date
          FOR XML PATH('')), 1, 1, '') as dates

from roster A
GROUP BY first, second, third, fourth

编辑:我已经很接近你想要的了,但还不完全,但是我不知道如何让它更接近,我想这是我所能走的,剩下的就看别人了:D:SQLFIDDLE语言

SELECT b.date as startdate, a.date as enddate, a.first, a.second, a.third, a.fourth FROM
(Select ROW_NUMBER() 
        OVER (ORDER BY first, second, third, fourth,date ) AS Row,
        date,
        first,second,third,fourth
from roster) A
JOIN 
(Select ROW_NUMBER() 
        OVER (ORDER BY first, second, third, fourth,date ) AS Row,
        date,
        first,second,third,fourth
from roster) B
ON A.row = b.row + 1
WHERE a.first = b.first
and a.second = b.second
and a.third = b.third
and a.fourth = b.fourth
UNION
select max(date) as startdate, null as enddate, first, second, third, fourth
FROM roster
group by first, second, third, fourth
having count(*) = 1;
rhfm7lfc

rhfm7lfc3#

我一直在寻找自己的方法来实现这一点,并发现您也可以使用窗口函数来实现这一点:

SELECT *,
  ARRAY_AGG(STRUCT(first, second, third, fourth)) OVER (
    ORDER BY date
    ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING 
  )[OFFSET(0)] prior_row
FROM
  roster r 
QUALIFY
  prior_row IS NULL
  OR prior_row <> STRUCT(first, second, third, fourth)

相关问题