将行转换为涉及日期的列
Convert Rows to Columns involving Dates
我是一名 SAS 程序员,具有 SQL 的基础知识。我正在尝试将 SAS 程序转换为 SQL 脚本,我需要帮助将 SQL 服务器中的行转换为列。
我尝试了本论坛提供的一些解决方案(如 PIVOT、Multiple Joins 等),但无法实现我所需要的。问题是,ID 的行数可能在 1 - 500(或更多)之间变化,我需要动态创建这些列。然而,在 SAS 中,我不必担心行数的变化,因为 SAS 会使用预定义的 procedures/methods(如 Proc Transpose 或 Arrays)自动完成。
这是我尝试使用的一些示例数据。
感谢您在这方面的帮助。
ID STARTDT ENDDT
1 1/1/2020 1/3/2020
1 2/25/2020 2/28/2020
1 3/10/2020 3/15/2020
2 1/1/2020 1/3/2020
2 2/25/2020 2/28/2020
2 3/10/2020 3/15/2020
2 3/20/2020 3/20/2020
2 3/25/2020 3/31/2020
3 1/1/2020 1/3/2020
4 2/25/2020 2/28/2020
4 3/10/2020 3/15/2020
期望的输出。
ID STDT1 ENDT1 STDT2 ENDT2 STDT3 ENDT3 STDT4 ENDT4 STDT5 ENDT5 ........... STDT(MAX) ENDT(MAX)
1 1/1/2020 1/3/2020 2/25/2020 2/28/2020 3/10/2020 3/15/2020
2 1/1/2020 1/3/2020 2/25/2020 2/28/2020 3/10/2020 3/15/2020 3/20/2020 3/20/2020 3/25/2020 3/31/2020
3 1/1/2020 1/3/2020
4 2/25/2020 2/28/2020 3/10/2020 3/15/2020
这是您的问题的一种可能解决方案:
-- create table
CREATE TABLE Dates
(
ID INT,
StartDt VARCHAR(20),
EndDt VARCHAR(20)
)
-- Add sample data
INSERT INTO Dates VALUES (1, '1/1/2020', '1/3/2020')
INSERT INTO Dates VALUES (1, '2/25/2020', '2/28/2020')
INSERT INTO Dates VALUES (1, '3/10/2020', '3/15/2020')
INSERT INTO Dates VALUES (2, '1/1/2020' ,'1/3/2020')
INSERT INTO Dates VALUES (2, '2/25/2020', '2/28/2020')
-- Create a CTE to get the sequence for multiple occurrences of the same ID
-- Sequence1 is used for the second pivot on EndDt
WITH cte AS
(
SELECT
[ID]
,[Sequence] = ROW_NUMBER() OVER(PARTITION BY [ID] ORDER BY [ID])
,[Sequence1] = 100 + ROW_NUMBER() OVER(PARTITION BY [ID] ORDER BY [ID])
,[StartDt]
,[EndDt]
FROM Dates
)
-- SELECY with PIVOT on multiple columns
SELECT
[ID]
,[1] AS startdt1
,[101] AS enddt1
,[2] AS startdt2
,[102] AS enddt2
,[3] AS startdt3
,[103] AS enddt3
FROM cte x
PIVOT
(
MAX(StartDt)
FOR [Sequence] IN ([1], [2], [3])
) p1
PIVOT
(
MAX(EndDt)
FOR [Sequence1] IN ([101], [102], [103])
) p2
ORDER BY ID
我是一名 SAS 程序员,具有 SQL 的基础知识。我正在尝试将 SAS 程序转换为 SQL 脚本,我需要帮助将 SQL 服务器中的行转换为列。
我尝试了本论坛提供的一些解决方案(如 PIVOT、Multiple Joins 等),但无法实现我所需要的。问题是,ID 的行数可能在 1 - 500(或更多)之间变化,我需要动态创建这些列。然而,在 SAS 中,我不必担心行数的变化,因为 SAS 会使用预定义的 procedures/methods(如 Proc Transpose 或 Arrays)自动完成。
这是我尝试使用的一些示例数据。
感谢您在这方面的帮助。
ID STARTDT ENDDT
1 1/1/2020 1/3/2020
1 2/25/2020 2/28/2020
1 3/10/2020 3/15/2020
2 1/1/2020 1/3/2020
2 2/25/2020 2/28/2020
2 3/10/2020 3/15/2020
2 3/20/2020 3/20/2020
2 3/25/2020 3/31/2020
3 1/1/2020 1/3/2020
4 2/25/2020 2/28/2020
4 3/10/2020 3/15/2020
期望的输出。
ID STDT1 ENDT1 STDT2 ENDT2 STDT3 ENDT3 STDT4 ENDT4 STDT5 ENDT5 ........... STDT(MAX) ENDT(MAX)
1 1/1/2020 1/3/2020 2/25/2020 2/28/2020 3/10/2020 3/15/2020
2 1/1/2020 1/3/2020 2/25/2020 2/28/2020 3/10/2020 3/15/2020 3/20/2020 3/20/2020 3/25/2020 3/31/2020
3 1/1/2020 1/3/2020
4 2/25/2020 2/28/2020 3/10/2020 3/15/2020
这是您的问题的一种可能解决方案:
-- create table
CREATE TABLE Dates
(
ID INT,
StartDt VARCHAR(20),
EndDt VARCHAR(20)
)
-- Add sample data
INSERT INTO Dates VALUES (1, '1/1/2020', '1/3/2020')
INSERT INTO Dates VALUES (1, '2/25/2020', '2/28/2020')
INSERT INTO Dates VALUES (1, '3/10/2020', '3/15/2020')
INSERT INTO Dates VALUES (2, '1/1/2020' ,'1/3/2020')
INSERT INTO Dates VALUES (2, '2/25/2020', '2/28/2020')
-- Create a CTE to get the sequence for multiple occurrences of the same ID
-- Sequence1 is used for the second pivot on EndDt
WITH cte AS
(
SELECT
[ID]
,[Sequence] = ROW_NUMBER() OVER(PARTITION BY [ID] ORDER BY [ID])
,[Sequence1] = 100 + ROW_NUMBER() OVER(PARTITION BY [ID] ORDER BY [ID])
,[StartDt]
,[EndDt]
FROM Dates
)
-- SELECY with PIVOT on multiple columns
SELECT
[ID]
,[1] AS startdt1
,[101] AS enddt1
,[2] AS startdt2
,[102] AS enddt2
,[3] AS startdt3
,[103] AS enddt3
FROM cte x
PIVOT
(
MAX(StartDt)
FOR [Sequence] IN ([1], [2], [3])
) p1
PIVOT
(
MAX(EndDt)
FOR [Sequence1] IN ([101], [102], [103])
) p2
ORDER BY ID