Sql 需要重点援助

Sql 需要重点援助,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

我有一张这样的桌子。表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 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我只希望我能投赞成票不止一次。很好的答案+我只希望我能多投一次票。答案很好。。!!