[英]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.