SQL Server 根据列更改行

yhuiod9q  于 2023-01-01  发布在  其他
关注(0)|答案(1)|浏览(134)

我正尝试在SQL Server中更改具有以下条件的行。
1.合并具有相似code的所有行,从第1行中获取第一个日期,从最后一行中获取最后一个日期。
1.不相似的行将保持原样。

CREATE TABLE ABCD(
    id int,
    FirstDate date,
    LastDate date,
    code varchar(23)
);

Insert into ABCD VALUES
(1, '2022-12-12','2022-12-12', 'A'),
(2, '2022-12-13','2022-12-13', 'A'),
(3, '2022-12-15','2022-12-15', 'A'),
(4, '2022-12-16','2022-2-16', 'B'),
(5, '2022-12-18','2022-12-18', 'A'),
(5, '2022-12-19','2022-12-19', 'A'),
(6, '2022-12-20','2022-12-20', 'C')

SELECT * from ABCD

预期结果为

(1, '2022-12-12','2022-12-15', 'A'),
(2, '2022-12-16','2022-2-16', 'B'),
(3, '2022-12-18','2022-12-19', 'A'),
(4, '2022-12-20','2022-12-20', 'C')

尝试

SELECT *
FROM ABCD #A
INNER JOIN ABCD #B on #A.code != #B.code AND #A.id = #B.id

我想不出任何逻辑来让这个工作。建议是高度赞赏。谢谢!

vqlkdk9b

vqlkdk9b1#

你可以用逻辑来做,它有几个步骤

  • 首先,根据行是否连续将它们“分组”在一起(例如,前三个A行,然后是B行,等等)
  • 要做到这一点,下面的答案使用2个步骤:首先,找到每一行是一个“新”组,并为这些行分配1。2然后对这些行进行累计-这将成为分组值。
  • 然后,按分组值分组-并获得最小和最大日期。
WITH ABCD_with_newvals AS
  (SELECT *, 
         CASE WHEN LAG(code, 1) OVER (ORDER BY ID) = [code] THEN 0 ELSE 1 END AS NewVal
  FROM ABCD
  ),
  ABCD_grouped AS
  (SELECT *,
         SUM(NewVal) OVER (ORDER BY ID) AS GroupNum
  FROM ABCD_with_newvals
  )
SELECT GroupNum, Code, MIN(FirstDate) AS FirstDate, MAX(LastDate) AS LastDate
  FROM ABCD_grouped
  GROUP BY GroupNum, Code
  ORDER BY GroupNum;

下面是一个db<>fiddle,其中包含了答案,并分解了各个步骤,以便您可以看到过程中每个点的数据。
哦-这是结果

GroupNum   Code   FirstDate    LastDate
1          A      2022-12-12   2022-12-15
2          B      2022-12-16   2022-02-16
3          A      2022-12-18   2022-12-19
4          C      2022-12-20   2022-12-20

相关问题