2017-06-14 61 views
0

我在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。所以我嘗試使用Efficiently convert rows to columns in sql server後的回答,但無法調整它來解決我的問題。有3列,而不是兩個,我需要考慮,也必須由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 

我知道我做錯了,讓我的期望輸出,但是當我嘗試更改數據透視表中的列名稱時,我得到了一些其他更改,或者在「PIVOT」運算符中提供了「無效列名」或「不正確的值」0.14「。

+0

你能告訴我們你的,你提到的答案的版本?爲什麼它不符合你想要的輸出? – SchmitzIT

+0

我編輯過的問題包括我試圖調整的SQL版本,以便提供所需的結果。我不認爲我理解它100%,但試圖。 – 300

回答

1

如果我們拿東西,在一步一個腳印,讓我們試着和第一做到這一點,而無需使用動態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忍者東西

爲了使這更動態一點,下面的工作:

我們開始通過聲明兩個變量,將持有的列和查詢:

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; 
+0

是的,這適用於現有的樣品臺。 – 300

+0

@ 300太棒了。那麼我是否認爲你需要更多的列呢?命名它們可能會有些棘手,但我們可以試試它。但是,上面的查詢可以用作創建您之後的動態SQL的基礎。 – SchmitzIT

+0

是的,我需要更多的列,但是他們會在6到23之間。但是我不知道將出現在table_name1中的行數 – 300

1

你可以做一個動態的關鍵點來獲得你想要的。下面是一個使用臨時表從你的例子爲例:

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, 
    '[email protected]+' 
from   
    (
    select 
     created_date, 
     complete_hour, 
     col_percent 
    from #table_name1 
    ) 
    as main 
    pivot 
    (
     max(col_percent) 
     for complete_hour in ('[email protected]+') 
    ) as p 
order by 
    created_date 
' 

exec sp_Executesql @sql 
+0

謝謝你的迴應傑西。我希望我可以將多個答覆標記爲答案。您的解決方案對我來說也很完美,但除了SchmitzIT之外,我無法將其標記爲答案。我對此表示歉意。 – 300

+0

所有的好,很高興你有你需要的。 – Jesse