Sql 需要重点援助
我有一张这样的桌子。表1Sql 需要重点援助,sql,sql-server,pivot,Sql,Sql Server,Pivot,我有一张这样的桌子。表1 Customer Product Value Quantity Order Number Dave Product 1 15 1 154 Dave Product 2 25 5 154 Dave Product 3 45 4 15 Rob Product 2 222 33 233 现在我要这个,表2 Customer Product 1 Quantity Product
Customer Product Value Quantity Order Number
Dave Product 1 15 1 154
Dave Product 2 25 5 154
Dave Product 3 45 4 15
Rob Product 2 222 33 233
现在我要这个,表2
Customer Product 1 Quantity Product 1 Value Price per item ( Value /Quantity) for Product 1 Product 2 Quantity Product 2 Value Price per item ( Value /Quantity) for Product 2 Product 3 Quantity Product 3 Value Price per item ( Value /Quantity) for Product 3 Order Number
Dave 1 15 15 5 25 5 null null null 154
Dave null null null null null Null 4 45 11.25 15
Rob null null null 33 222 6.727272727 null null null 233
我在考虑一些支点,但不确定如何构建它。此外,表1中的产品数量不是固定不变的。为了得到结果,我建议对数据应用unpivot和pivot UNPIVOT将把表中的列数据转换成行。数据解除锁定后,就可以应用透视 由于您使用的是SQL Server 2008+,所以可以使用交叉应用with the VALUES子句来取消PIVOT。在2008年之前,您可以使用UNPIVOT功能。取消打印数据的代码为:
select t.customer,
replace(t.product, ' ', '')+'_'+c.col piv_col,
c.val,
t.ordernumber
from table1 t
cross apply
(
values
('value', cast(value as varchar(10))),
('quantity', cast(quantity as varchar(10))),
('PricePerUnit', cast((value/quantity) *1.0 as varchar(10)))
) c (col, val);
看。这会将数据转换为以下格式:
| CUSTOMER | PIV_COL | VAL | ORDERNUMBER |
---------------------------------------------------------
| Dave | Product1_value | 15 | 154 |
| Dave | Product1_quantity | 1 | 154 |
| Dave | Product1_PricePerUnit | 15.0 | 154 |
| Dave | Product2_value | 25 | 154 |
您可以看到,Dave
order154的行已经变成了行,我已经创建了将用于透视(piv\u col
)的新列名。此列已将产品名称连接到上一列标题(值、数量)的起始位置
由于数据位于一行中,因此可以轻松地将pivot函数应用于数据。最终代码为:
select customer,
Product1_quantity, Product1_value, Product1_PricePerUnit,
Product2_quantity, Product2_value, Product2_PricePerUnit,
Product3_quantity, Product3_value, Product3_PricePerUnit,
orderNumber
from
(
select t.customer,
replace(t.product, ' ', '')+'_'+c.col piv_col,
c.val,
t.ordernumber
from table1 t
cross apply
(
values
('value', cast(value as varchar(10))),
('quantity', cast(quantity as varchar(10))),
('PricePerUnit', cast((value/quantity) *1.0 as varchar(10)))
) c (col, val)
) d
pivot
(
max(val)
for piv_col in(Product1_quantity, Product1_value, Product1_PricePerUnit,
Product2_quantity, Product2_value, Product2_PricePerUnit,
Product3_quantity, Product3_value, Product3_PricePerUnit)
) piv;
看
如果您有已知数量的产品,上述方法非常有效,但如果没有,则需要使用动态SQL
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(replace(t.product, ' ', '')+'_'+c.col)
from Table1 t
cross apply
(
values ('value', 1), ('quantity', 0),('PricePerUnit', 3)
) c (col, so)
group by product, col, so
order by product, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT customer, ' + @cols + ', ordernumber
from
(
select t.customer,
replace(t.product, '' '', '''')+''_''+c.col piv_col,
c.val,
t.ordernumber
from table1 t
cross apply
(
values
(''value'', cast(value as varchar(10))),
(''quantity'', cast(quantity as varchar(10))),
(''PricePerUnit'', cast((value/quantity) *1.0 as varchar(10)))
) c (col, val)
) d
pivot
(
max(val)
for piv_col in (' + @cols + ')
) p '
execute(@query);
看。这些查询给出了以下结果:
| CUSTOMER | PRODUCT1_QUANTITY | PRODUCT1_VALUE | PRODUCT1_PRICEPERUNIT | PRODUCT2_QUANTITY | PRODUCT2_VALUE | PRODUCT2_PRICEPERUNIT | PRODUCT3_QUANTITY | PRODUCT3_VALUE | PRODUCT3_PRICEPERUNIT | ORDERNUMBER |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Dave | (null) | (null) | (null) | (null) | (null) | (null) | 4 | 45 | 11.0 | 15 |
| Dave | 1 | 15 | 15.0 | 5 | 25 | 5.0 | (null) | (null) | (null) | 154 |
| Rob | (null) | (null) | (null) | 33 | 222 | 6.0 | (null) | (null) | (null) | 233 |
为了得到结果,我建议对数据应用unpivot和pivot UNPIVOT将把表中的列数据转换成行。数据解除锁定后,就可以应用透视 由于您使用的是SQL Server 2008+,所以可以使用交叉应用with the VALUES子句来取消PIVOT。在2008年之前,您可以使用UNPIVOT功能。取消打印数据的代码为:
select t.customer,
replace(t.product, ' ', '')+'_'+c.col piv_col,
c.val,
t.ordernumber
from table1 t
cross apply
(
values
('value', cast(value as varchar(10))),
('quantity', cast(quantity as varchar(10))),
('PricePerUnit', cast((value/quantity) *1.0 as varchar(10)))
) c (col, val);
看。这会将数据转换为以下格式:
| CUSTOMER | PIV_COL | VAL | ORDERNUMBER |
---------------------------------------------------------
| Dave | Product1_value | 15 | 154 |
| Dave | Product1_quantity | 1 | 154 |
| Dave | Product1_PricePerUnit | 15.0 | 154 |
| Dave | Product2_value | 25 | 154 |
您可以看到,Dave
order154的行已经变成了行,我已经创建了将用于透视(piv\u col
)的新列名。此列已将产品名称连接到上一列标题(值、数量)的起始位置
由于数据位于一行中,因此可以轻松地将pivot函数应用于数据。最终代码为:
select customer,
Product1_quantity, Product1_value, Product1_PricePerUnit,
Product2_quantity, Product2_value, Product2_PricePerUnit,
Product3_quantity, Product3_value, Product3_PricePerUnit,
orderNumber
from
(
select t.customer,
replace(t.product, ' ', '')+'_'+c.col piv_col,
c.val,
t.ordernumber
from table1 t
cross apply
(
values
('value', cast(value as varchar(10))),
('quantity', cast(quantity as varchar(10))),
('PricePerUnit', cast((value/quantity) *1.0 as varchar(10)))
) c (col, val)
) d
pivot
(
max(val)
for piv_col in(Product1_quantity, Product1_value, Product1_PricePerUnit,
Product2_quantity, Product2_value, Product2_PricePerUnit,
Product3_quantity, Product3_value, Product3_PricePerUnit)
) piv;
看
如果您有已知数量的产品,上述方法非常有效,但如果没有,则需要使用动态SQL
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(replace(t.product, ' ', '')+'_'+c.col)
from Table1 t
cross apply
(
values ('value', 1), ('quantity', 0),('PricePerUnit', 3)
) c (col, so)
group by product, col, so
order by product, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT customer, ' + @cols + ', ordernumber
from
(
select t.customer,
replace(t.product, '' '', '''')+''_''+c.col piv_col,
c.val,
t.ordernumber
from table1 t
cross apply
(
values
(''value'', cast(value as varchar(10))),
(''quantity'', cast(quantity as varchar(10))),
(''PricePerUnit'', cast((value/quantity) *1.0 as varchar(10)))
) c (col, val)
) d
pivot
(
max(val)
for piv_col in (' + @cols + ')
) p '
execute(@query);
看。这些查询给出了以下结果:
| CUSTOMER | PRODUCT1_QUANTITY | PRODUCT1_VALUE | PRODUCT1_PRICEPERUNIT | PRODUCT2_QUANTITY | PRODUCT2_VALUE | PRODUCT2_PRICEPERUNIT | PRODUCT3_QUANTITY | PRODUCT3_VALUE | PRODUCT3_PRICEPERUNIT | ORDERNUMBER |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Dave | (null) | (null) | (null) | (null) | (null) | (null) | 4 | 45 | 11.0 | 15 |
| Dave | 1 | 15 | 15.0 | 5 | 25 | 5.0 | (null) | (null) | (null) | 154 |
| Rob | (null) | (null) | (null) | 33 | 222 | 6.0 | (null) | (null) | (null) | 233 |
什么版本的sql server?您想让标题显示实际的产品名称(汽车等)还是想要普通产品1?实际的产品名称请使用什么版本的sql server?您想让标题显示实际的产品名称(汽车等)或者你想要一个普通的产品1?实际的产品名称请+1我只希望我能投赞成票不止一次。很好的答案+我只希望我能多投一次票。答案很好。。!!