旋转数据库表

问题描述 投票:2回答:2

想象我有一个具有以下格式的数据库表:

╔══════════════════════╗
║ Name   Quarter Sales ║
╠══════════════════════╣
║ Joe    Q1      700   ║
║ Joe    Q2      650   ║
║ Joe    Q3      660   ║
║ Bill   Q1      500   ║
║ Bill   Q2      520   ║
║ Bill   Q3      550   ║
║ Bob    Q2      200   ║
║ Bob    Q3      250   ║
╚══════════════════════╝

我需要按以下格式进行旋转。在这里,每个季度的每个不同的值都变成一列,每个季度的销售额就是每个销售人员相应列的值。

╔══════════════════════╗
║ Name   Q1   Q2   Q3  ║
╠══════════════════════╣
║ Joe    700  650  660 ║
║ Bill   500  520  550 ║
║ Bob         200  250 ║
╚══════════════════════╝

SQL可能吗?我正在使用SQL Server,但如果可能的话,建议使用普通SQL。

我们不知道前面四分之一列中的值,即,我们不仅限于Q1 / Q2 / Q3等。假设用户可以输入Q1,Quarter 1或他们喜欢的其他任何值。

sql sql-server pivot
2个回答
2
投票

您可以尝试将聚集条件SUMCASE WHEN一起使用

SELECT Name,
       SUM(CASE WHEN Quarter = 'Q1' THEN Sales ELSE 0 END) 'Q1',
       SUM(CASE WHEN Quarter = 'Q2' THEN Sales ELSE 0 END) 'Q2',
       SUM(CASE WHEN Quarter = 'Q3' THEN Sales ELSE 0 END) 'Q3'
FROM T
GROUP BY Name

1
投票

我建议改用PIVOT方法。

[通过查看上面的评论,您确实希望将季度Q1,Q2 ...动态,因为您可能没有季度的特定值。

我在这里更新了答案,请尝试一下。

PivotSample替换TableName

IF OBJECT_ID('tempdb..##TEMP_TBL') IS NOT NULL
DROP TABLE ##TEMP_TBL

--GET all pivoted column -> [Q1], [Q12]...
DECLARE @pivot_col AS NVARCHAR(MAX)
;WITH distinct_col AS
(
    SELECT DISTINCT [Quarter]
    FROM PivotSample
)
SELECT @pivot_col = COALESCE(@pivot_col + ',', '') + QUOTENAME([Quarter])
FROM distinct_col

--Generate query, to pivot the data given
DECLARE @query AS NVARCHAR(MAX)
SET @query = 
    N'SELECT [Name], ' + @pivot_col + ' ' +
    'INTO ##TEMP_TBL
    FROM PivotSample
    PIVOT
    (
        SUM(Sales)
        FOR [Quarter] IN ( ' + @pivot_col + ' )
    ) AS pvt'

--Execute query, to insert result into ##TEMP_TBL
EXEC sp_executesql @query


--GET all [Quarter] column, to add in ISNULL after PIVOT column -> e.g:  ISNULL([Q1], 0) AS [Q1], ISNULL([Q2], 0) AS [Q2]...
DECLARE @col_name AS NVARCHAR(MAX)
;WITH distinct_col AS
(
    SELECT DISTINCT [Quarter]
    FROM PivotSample
)
SELECT @col_name =
        STUFF(
        (
            SELECT ', ISNULL(' + QUOTENAME([Quarter]) + ', 0) AS ' + QUOTENAME([Quarter])
            FROM distinct_col
            ORDER BY [Quarter]
            FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)')
        ,1 , 1, '')

--Generate query_result, to get result from ##TEMP_TBL after add in ISNULL
DECLARE @query_result AS NVARCHAR(MAX)
SET @query_result = 
    N'SELECT [Name], ' + @col_name + ' ' +
    'FROM ##TEMP_TBL
    ORDER BY [Name]'

--Execute query_result, final result shown
EXEC sp_executesql @query_result
© www.soinside.com 2019 - 2024. All rights reserved.