vha*_*lgi 9 sql t-sql ssis sql-server-2008 business-intelligence
在SSIS有一个名为Pivot转换的任务,它将列更改为行,但是如何使用t-sql在sql server中执行相同的任务?
这是我的样本表
location product qty
-----------------------
delhi PEPSI 100
GURGAON CAKE 200
NOIDA APPLE 150
delhi cake 250
Run Code Online (Sandbox Code Playgroud)
因此,在使用ssis工具将枢轴转换为ON位置作为setkey并将产品作为枢轴键之后,o/p变为
location pepsi cake apple
delhi 100 null null
GURGAON null 200 null
NOIDA null null 150
delhi null 250 null
Run Code Online (Sandbox Code Playgroud)
PIVOT像这样使用表运算符:
SELECT *
FROM tablename
PIVOT
(
MAX(qty)
FOR product IN([pepsi], [cake], [apple])
) as p;
Run Code Online (Sandbox Code Playgroud)
注意:
如果你想获得总和使用或任何其他聚合函数,我使用了MAX聚合函数.qtySUM
您必须手动编写要旋转的列的值,如果要动态执行此操作而不是手动编写,则必须使用动态sql来执行此操作.
像这样:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
select @cols = STUFF((SELECT distinct ',' +
QUOTENAME(product)
FROM tablename
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT @query = 'SELECT *
FROM tablename
PIVOT
(
MAX(qty)
FOR product IN(' + @cols + ')) AS p;';
execute(@query);
Run Code Online (Sandbox Code Playgroud)
数据透视请求涉及三个逻辑处理阶段,每个阶段都包含相关元素
因此,在您的案例中根据需求映射这些阶段:
‘Location’ ‘Product’列值进行,最终列名称为:'Pepsi','Cake','Apple'.‘Qty’ 值将被聚合以产生用于分组和扩展元素的交叉值将这些值放在标准的Pivot语句中:
SELECT ...
FROM <source_table_or_table_expression>
PIVOT(<agg_func>(<aggregation_element>)
FOR <spreading_element>
IN (<list_of_target_columns>)) AS <result_table_alias>
Run Code Online (Sandbox Code Playgroud)
您的查询变为:
select location ,[PEPSI], [CAKE],[APPLE]
from table1
pivot (sum(qty)
for product
in ( [PEPSI], [CAKE],[APPLE])) AS T
Run Code Online (Sandbox Code Playgroud)
重要的是要注意,使用PIVOT运算符时,您不会显式指定分组元素,从而无需在查询中使用GROUP BY.PIVOT运算符隐式地将分组元素计算为源表(或表表达式)中未指定为扩展元素或聚合元素的所有属性.因此,您必须确保PIVOT运算符的源表除了分组,传播和聚合元素之外没有任何属性,因此在指定传播和聚合元素之后,剩下的唯一属性是您打算作为分组元素的属性.您可以通过不直接将PIVOT运算符应用于原始表来实现此目的,而是将表单表达式仅包含表示旋转元素的属性而不包含其他元素.
select location ,[PEPSI], [CAKE],[APPLE]
from (select location,product,qty
from table1 ) as SourceTable
pivot (sum(qty)
for product
in ( [PEPSI], [CAKE],[APPLE])) AS T
Run Code Online (Sandbox Code Playgroud)
希望这有助于更好地理解Pivot运营商!
编辑:添加了Unpivot运算符概念:
与Pivoting一样,Unpivoting也涉及3个逻辑阶段:
将这些值放在标准的Unpivot语句中:
SELECT ...
FROM <source_table_or_table_expression>
UNPIVOT(<target_col_to_hold_source_col_values>
FOR <target_col_to_hold_source_col_names> IN(<list_of_source_columns>)) AS
<result_table_alias>;
Run Code Online (Sandbox Code Playgroud)
根据您的案例中的要求映射这些阶段:
<target_col_to_hold_source_col_values>=将保存源列值的列的名称,即:保存列值,[Pepsi], [Cake],[Apple]即100,250 ......您希望将一个列作为:Qty<target_col_to_hold_source_col_names>=将保存源列名称的列的名称,即:保存[Pepsi], [Cake],[Apple]要使用一列的列名称:product<list_of_source_columns> =您感兴趣的源表中列的名称,即: [Pepsi], [Cake],[Apple]您的查询变为:
SELECT location,product,qty
FROM #temp
UNPIVOT(qty
FOR product
IN([Pepsi],[Cake],[Apple])) AS U;
Run Code Online (Sandbox Code Playgroud)
我在临时表中添加了上面的Pivot语句的结果#temp.
这里要注意的重要一点是: 取消透视数据透视表无法恢复原始表,因为透视会导致由于聚合而丢失详细信息.
| 归档时间: |
|
| 查看次数: |
8349 次 |
| 最近记录: |