Sql uce动态列数?这似乎生成了与我的原始代码相同的结果集。我编辑了这个问题,以澄清我发布的结果集不正确,D的序列应该是红色-->蓝色-->红色.Nice。不过,有一点需要注意:这种方法在转换年份或在几个月内出现间隔时将失败。如果这不是数据组织方式的问题,那么

Sql uce动态列数?这似乎生成了与我的原始代码相同的结果集。我编辑了这个问题,以澄清我发布的结果集不正确,D的序列应该是红色-->蓝色-->红色.Nice。不过,有一点需要注意:这种方法在转换年份或在几个月内出现间隔时将失败。如果这不是数据组织方式的问题,那么,sql,sql-server,group-by,window-functions,Sql,Sql Server,Group By,Window Functions,uce动态列数?这似乎生成了与我的原始代码相同的结果集。我编辑了这个问题,以澄清我发布的结果集不正确,D的序列应该是红色-->蓝色-->红色.Nice。不过,有一点需要注意:这种方法在转换年份或在几个月内出现间隔时将失败。如果这不是数据组织方式的问题,那么这可能是最快的实现。 create table #colors (mon int, grp varchar(1), color varchar(5)) insert #colors values (201501,'A','Red'), (2


uce动态列数?这似乎生成了与我的原始代码相同的结果集。我编辑了这个问题,以澄清我发布的结果集不正确,D的序列应该是红色-->蓝色-->红色.Nice。不过,有一点需要注意:这种方法在转换年份或在几个月内出现间隔时将失败。如果这不是数据组织方式的问题,那么这可能是最快的实现。
create table #colors (mon int, grp varchar(1), color varchar(5)) 
insert #colors values 
(201501,'A','Red'),
(201502,'A','Red'),
(201503,'A','Red'),
(201504,'A','Red'),
(201505,'A','Red'),
(201506,'A','Red'),
(201501,'B','Red'),
(201502,'B','Red'),
(201503,'B','Blue'),
(201504,'B','Blue'),
(201505,'B','Blue'),
(201506,'B','Blue'),
(201501,'C','Red'),
(201502,'C','Red'),
(201503,'C','Blue'),
(201504,'C','Green'),
(201505,'C','Green'),
(201506,'C','Green'),
(201501,'D','Red'),
(201502,'D','Red'),
(201503,'D','Blue'),
(201504,'D','Blue'),
(201505,'D','Red'),
(201506,'D','Red')
; with colors (grp, color, mon, rn) as (
    select  grp
        ,   color
        ,   mon
        ,   row_number() over (partition by grp order by mon asc) rn
    from    (
        select  grp
            ,   color
            ,   max(mon) mon
        from    #colors
        group by grp, color
        ) as z
    )
    select  grp
        ,   firstColor
        ,   firstMonth
        ,   secondColor
        ,   secondMonth
        ,   thirdColor
        ,   thirdMonth
    from    (
        select  c1.grp
            ,   c1.color firstColor
            ,   c1.mon firstMonth
            ,   c2.color secondColor
            ,   c2.mon secondMonth
            ,   c3.color thirdColor
            ,   c3.mon thirdMonth
            ,   row_number() over (partition by c1.grp order by c1.mon asc) rn
        from    colors c1 left outer join colors c2 on (
                        c1.grp = c2.grp
                    and c1.color <> c2.color
                    and c1.rn = c2.rn - 1
                ) left outer join colors c3 on (
                        c1.grp = c3.grp
                    and c2.color <> c3.color
                    and c2.rn = c3.rn - 1
                )
        ) as d
    where   rn = 1
    order by grp
WITH colors AS(
    SELECT *
        , ROW_NUMBER() OVER (partition by grp ORDER BY mon desc) RowNumberOrder

    FROM colorss
)
select * from (
SELECT row_number() over (partition by c1.grp order by c1.rowNumberOrder asc) rn, c1.grp
            ,   c1.color firstColor
            ,   c1.mon firstMonth
            ,   c2.color secondColor
            ,   c2.mon secondMonth
            ,   c3.color thirdColor
            ,   c3.mon thirdMonth
FROM colors c1 
  left join colors c2 on c1.grp = c2.grp and c1.RowNumberOrder < c2.rowNumberOrder and c1.color <> c2.color
  left join colors c3 on c3.grp = c2.grp and c2.RowNumberOrder < c3.rowNumberOrder and c2.color <> c3.color
  ) a where rn = 1
WITH nCTE (mon, grp, color, n) AS (
  SELECT *, ROW_NUMBER() OVER(PARTITION BY grp ORDER BY mon) n
  FROM colors
), monthsCTE (mon, grp, color, n) AS (
  SELECT l.mon, l.grp, l.color, ROW_NUMBER() OVER(PARTITION BY l.grp ORDER BY l.mon) n
  FROM nCTE l LEFT JOIN nCTE r
    ON l.grp = r.grp AND l.n = r.n - 1
  WHERE l.color != r.color OR r.color IS NULL
)

SELECT m1.grp, m1.color, m1.mon, m2.color, m2.mon, m3.color, m3.mon
FROM monthsCTE m1 LEFT JOIN monthsCTE m2
  ON m1.grp = m2.grp AND m2.n = 2 LEFT JOIN monthsCTE m3
  ON m1.grp = m3.grp AND m3.n = 3
WHERE m1.n = 1
ORDER BY 1
;with nextcols as
(
    select grp, color, mon, lead(color, 1, 'none') over (partition by grp order by mon  ) nextcol from #colors
)
, ranked as
(
    select *, ROW_NUMBER() over (partition by grp order by mon) MonthIndex from nextcols where color <> nextcol
) 
--perhaps you could go pivoting here, but joining on the monthindex works
select r1.grp, r1.color firstCol, r1.mon firstMon, r2.color secondCol, r2.mon secondMon, r3.color thirdCol, r3.mon thirdMon
from ranked r1
left join ranked r2 on r2.grp=r1.grp and r2.MonthIndex = 2
left join ranked r3 on r3.grp=r1.grp and r3.MonthIndex = 3
where r1.MonthIndex = 1