具有多列的SQL Pivot

时间:2010-07-13 20:54:40

标签: sql sql-server sql-server-2008 pivot

需要sql server 2008中的pivot子句的帮助。 我有一个包含此信息的表格:

Weekno    DayOfWeek     FromTime    ToTime
1         2             10:00       14:00
1         3             10:00       14:00
2         3             08:00       13:00
2         4             09:00       13:00
2         5             14:00       22:00
3         1             06:00       13:00
3         4             06:00       13:00
3         5             14:00       22:00

我想将其转换为如下所示的表格:

Week    Start1    End1    Start2    End2    Start3    End3    Start4    End4    Start5    End5    Start6    End6    Start7    End7
1                         10:00     14:00   10:00     14:00
2                                           08:00     13:00   09:00     13:00   14:00     22:00
3       06:00     13:00                                       06:00     13:00   14:00     22:00

透视查询有什么办法吗? 请写一个关于如何做的回答。

我很感激这方面的任何帮助。提前致谢。

3 个答案:

答案 0 :(得分:15)

这是枢轴版本:

https://data.stackexchange.com/stackoverflow/query/7295/so3241450

-- SO3241450

CREATE TABLE #SO3241450 (
    Weekno int NOT NULL
    ,DayOfWeek int NOT NULL
    ,FromTime time NOT NULL
    ,ToTime time NOT NULL
)

INSERT INTO #SO3241450 VALUES
(1, 2, '10:00', '14:00')
,(1, 3, '10:00', '14:00')
,(2, 3, '08:00', '13:00')
,(2, 4, '09:00', '13:00')
,(2, 5, '14:00', '22:00')
,(3, 1, '06:00', '13:00')
,(3, 4, '06:00', '13:00')
,(3, 5, '14:00', '22:00')

;WITH Base AS (
    SELECT Weekno, DayOfWeek, FromTime AS [Start], ToTime AS [End]
    FROM #SO3241450
)
,norm AS (
SELECT Weekno, ColName + CONVERT(varchar, DayOfWeek) AS ColName, ColValue
FROM Base
UNPIVOT (ColValue FOR ColName IN ([Start], [End])) AS pvt
)
SELECT *
FROM norm
PIVOT (MIN(ColValue) FOR ColName IN ([Start1], [End1], [Start2], [End2], [Start3], [End3], [Start4], [End4], [Start5], [End5], [Start6], [End6], [Start7], [End7])) AS pvt​

答案 1 :(得分:8)

我个人讨厌枢轴 - 难以阅读和不畏。

CREATE TABLE #test
(
    WeekNo int,
    [DayOfWeek] int,
    FromTime time,
    ToTime time
    )

INSERT INTO #test
SELECT 1,2,'10:00','14:00'
UNION ALL
SELECT 1,3,'10:00','14:00'
UNION ALL
SELECT 2,3,'08:00','13:00'
UNION ALL
SELECT 2,4,'09:00','13:00'
UNION ALL
SELECT 2,5,'14:00','22:00'
UNION ALL
SELECT 3,1,'06:00','13:00'
UNION ALL
SELECT 3,4,'06:00','13:00'
UNION ALL
SELECT 3,5,'14:00','22:00'

SELECT WeekNo, 
    MAX(CASE WHEN DayOfWeek = 1 THEN FromTime ELSE NULL END)  AS Start1,
    MAX(CASE WHEN DayOfWeek = 1 THEN ToTime ELSE NULL END)  AS End1,
    MAX(CASE WHEN DayOfWeek = 2 THEN FromTime ELSE NULL END)  AS Start2,
    MAX(CASE WHEN DayOfWeek = 2 THEN ToTime ELSE NULL END)  AS End2,
    MAX(CASE WHEN DayOfWeek = 3 THEN FromTime ELSE NULL END)  AS Start3,
    MAX(CASE WHEN DayOfWeek = 3 THEN ToTime ELSE NULL END)  AS End3,
    MAX(CASE WHEN DayOfWeek = 4 THEN FromTime ELSE NULL END)  AS Start4,
    MAX(CASE WHEN DayOfWeek = 4 THEN ToTime ELSE NULL END)  AS End4,
    MAX(CASE WHEN DayOfWeek = 5 THEN FromTime ELSE NULL END)  AS Start5,
    MAX(CASE WHEN DayOfWeek = 5 THEN ToTime ELSE NULL END)  AS End5,
    MAX(CASE WHEN DayOfWeek = 6 THEN FromTime ELSE NULL END)  AS Start6,
    MAX(CASE WHEN DayOfWeek = 6 THEN ToTime ELSE NULL END)  AS End6,
    MAX(CASE WHEN DayOfWeek = 7 THEN FromTime ELSE NULL END)  AS Start7,
    MAX(CASE WHEN DayOfWeek = 7 THEN ToTime ELSE NULL END)  AS End7
    FROM #test
    GROUP BY WeekNo

它会从袜子上吹掉袜子;表现明智。

答案 2 :(得分:0)

我认为CASE WHEN只有在唯一的Weekno和DayofWeek时才有效,因为它只返回最新开始和结束时间的记录并过滤掉其余部分。 示例

Weekno    DayOfWeek     FromTime    ToTime
1         2             10:00       14:00
1         2             07:00       09:00
2         3             08:00       13:00
2         4             09:00       13:00

它只会返回DayofWeek 2的第一行第一行并跳过第二行。