簡體   English   中英

如何將單個列中的值顯示為多個並按另一列分組

[英]How to display values in a single column into multiple and group by another column

我在SQL Server 2012中使用以下方法創建了一個數據庫表“ table_name1”:

CREATE TABLE table_name1 (
    created_date date,
    complete_hour int,
    col_percent float
);

INSERT INTO table_name1 values
('2017-06-14', 8, 0.3),
('2017-06-14', 9, 1.96),
('2017-06-14', 10, 3.92),
('2017-06-07', 8, 0.17),
('2017-06-07', 9, 2.87),
('2017-06-07', 10, 3.72),
('2017-05-31', 7, 0.14),
('2017-05-31', 8, 0.72),
('2017-05-31', 9, 3.77),
('2017-05-31', 10, 5.8);

我想做的是得到如下結果:

created_date    col1    col2    col3    col4
2017-06-14      BLANK   0.3     1.96    3.92
2017-06-07      BLANK   0.17    2.87    3.72
2017-05-31      0.14    0.72    3.77    5.8

我嘗試使用數據透視表,因為table_name1中的行數會不斷變化,我想我必須使用動態sql。 因此,我嘗試使用sql server post 中將行有效地轉換為列的答案,但無法對其進行調整以解決我的問題。 我需要考慮3列而不是2列,也必須按created_date分組。

我可以獲取有關如何執行此操作的建議嗎?

編輯:我試圖遵循的答案的修改版本是:

DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(col_percent) 
                    from table_name1
                    group by created_date, complete_hour, col_percent
                    order by complete_hour
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = N'SELECT ' + @cols + N' from 
             (
                select created_date, col_percent
                from table_name1                
            ) x
            pivot 
            (
                max(created_date)
                for col_percent in (' + @cols + N')
            ) p '

exec sp_executesql @query;

結果如下:

0.14        0.72        0.17        0.3         3.77        2.87        1.96        5.8         3.72        3.92
2017-05-31  2017-05-31  2017-06-07  2017-06-14  2017-05-31  2017-06-07  2017-06-14  2017-05-31  2017-06-07  2017-06-14

我知道我在獲取所需的輸出時做錯了,但是當我嘗試在數據透視圖中更改列名稱時,我得到了或進行了其他一些更改,得到了“無效的列名”或“提供了不正確的值“ 0.14” PIVOT運算符。”

您可以動態地獲取所需的內容。 這是使用示例中的臨時表的示例:

CREATE TABLE #table_name1 (
    created_date date,
    complete_hour int,
    col_percent float
);

INSERT INTO #table_name1 values
('2017-06-14', 8, 0.3),
('2017-06-14', 9, 1.96),
('2017-06-14', 10, 3.92),
('2017-06-07', 8, 0.17),
('2017-06-07', 9, 2.87),
('2017-06-07', 10, 3.72),
('2017-05-31', 7, 0.14),
('2017-05-31', 8, 0.72),
('2017-05-31', 9, 3.77),
('2017-05-31', 10, 5.8);


declare @sql nvarchar(max),
        @pvtColumns nvarchar(max),
        @selectColumns nvarchar(max)

select @pvtColumns = (
                        select ''+PivotColumns+','
                        from (
                            select distinct
                                    '['+convert(Varchar(10), complete_hour)+']' as PivotColumns, complete_hour
                            from #table_name1 
                            ) as b
                        order by complete_hour
                        for xml path('')
                     )

select @pvtColumns = substring(@pvtColumns,1,len(@pvtColumns)-1) 


set @sql = 

'
select 
    p.created_date,
    '+@pvtColumns+'
from        
    (
    select 
        created_date,
        complete_hour,
        col_percent
    from #table_name1 
    )
    as main
    pivot
    (
        max(col_percent)
        for complete_hour in ('+@pvtColumns+')
    ) as p
order by 
    created_date
'

exec sp_Executesql @sql

如果我們一次只邁出一步,那就先嘗試不使用動態sql來做到這一點。

我相信此查詢會產生您正在尋找的結果:

SELECT created_date, [7] AS col1, [8] AS col2, [9] AS col3, [10] AS col4
FROM 
    (
        select created_date, complete_hour, col_percent
        from table_name1                
    ) x
    pivot 
    (
        max(col_percent)
        for complete_hour in ([7],[8],[9],[10])
    ) p 
    ORDER BY created_date DESC

輸出:

created_date    col1    col2    col3    col4
2017-06-14      NULL    0,3     1,96    3,92
2017-06-07      NULL    0,17    2,87    3,72
2017-05-31      0,14    0,72    3,77    5,8

****更新:OP確認的結果看起來正確。 現在為一些動態sql ninja-stuff

為了使它更具動態性,可以執行以下操作:

我們首先聲明將包含列和查詢的兩個變量:

DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX)

接下來,我們確定要從表中獲取的列。 在我們的例子中,這是complete_hour 看到這些最有可能在幾天內重復出現,而我們只想要它們一次,我們GROUP BY complete_hour

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(complete_hour) 
                    from table_name1
                    group by complete_hour
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

現在我們可以測試變量中的內容:

PRINT @cols 

根據提供的測試數據,當前它將包含

[7],[8],[9],[10]

在現實生活中,這將是每個不同的complete_hour值的值。

繼續構建查詢:

set @query = N'SELECT created_date, ' + @cols + N' from 
             (
                select created_date, complete_hour, col_percent
                from table_name1                
            ) x
            pivot 
            (
                max(col_percent)
                for complete_hour in (' + @cols + N')
            ) p 
            ORDER BY created_date DESC
        '

您需要created_date列,該列必須在SELECT語句中。 我們還需要complete_hour的每個值,這是我們存儲在@cols中的值。

我們實際上想獲取所有內容,因此我們選擇所有三列,然后每隔complete_hour旋轉一次col_percent。

最后,我們按created_date排序,最新日期顯示在最前面。

然后我們可以執行:

exec sp_executesql @query;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM