SQL 服务器使用 where 条件创建 Unpivot table

SQL Server create Unpivot table with where condition

这是我的样本table

---+-------------+------------------+------------------+------------------+--------------------+--------------------+--------------------+
| Id|  CompanyName|part1_sales_amount|part2_sales_amount|part3_sales_amount|part1_sales_quantity|part2_sales_quantity|part3_sales_quantity|
+---+-------------+------------------+------------------+------------------+--------------------+--------------------+--------------------+
|  1|   FastCarsCo|                 1|                 2|                 3|                   4|                   5|                   6|
|  2|TastyCakeShop|                 4|                 5|                 6|                   4|                   5|                   6|
|  3|     KidsToys|                 7|                 8|                 9|                   7|                   8|                   9|
|  4|   FruitStall|                10|                11|                12|                  10|                  11|                  12|
+---+-------------+------------------+------------------+------------------+--------------------+--------------------+--------------------+

这是我想要的输出 table

+---+-------------+------------------+------------------+------------------+
| Id|  CompanyName|Account           |amount            |quantity          |
+---+-------------+------------------+------------------+------------------+
|  1|   FastCarsCo|       part1_sales|                 1|                 1| 
|  1|   FastCarsCo|       part2_sales|                 2|                 2|
|  1|   FastCarsCo|       part3_sales|                 3|                 3|
|  2|TastyCakeShop|       part1_sales|                 4|                 4|
|  2|TastyCakeShop|       part2_sales|                 5|                 5| 
|  2|TastyCakeShop|       part3_sales|                 6|                 6| 
|  3|     KidsToys|       part1_sales|                 7|                 7|
|  3|     KidsToys|       part2_sales|                 8|                 8|
|  3|     KidsToys|       part3_sales|                 9|                 9|
|  4|   FruitStall|       part1_sales|                10|                10|
|  4|   FruitStall|       part2_sales|                11|                11|
|  4|   FruitStall|       part3_sales|                12|                12| 
+---+-------------+------------------+------------------+------------------+

我已经做过的事情

SELECT 
Id,
CompanyName,
REPLACE ( acc , '_amount' , '' ) AS Account,
amount,
quantity
FROM
(
SELECT Id, CompanyName, part1_sales_amount ,part2_sales_amount ,part3_sales_amount ,part1_sales_quantity ,part2_sales_quantity ,part3_sales_quantity 
FROM privot
) src

UNPIVOT
(
amount FOR acc IN (part1_sales_amount ,part2_sales_amount ,part3_sales_amount )
) pvt1

UNPIVOT
(
quantity FOR acc1 IN (part1_sales_quantity, part2_sales_quantity, part3_sales_quantity )
) pvt2

它给出了一些结果,但似乎也有一些意想不到的记录(比如交叉连接)。所以我的最后一步 WHERE 子句,我应该在 WHERE 中写什么 clause.I 尝试了很多东西,但没有一个是正确的。

注意:在我的真实数据库中,有近 200 列像 part1_sales_amount 和 part1_sales_quantity

请多多指教。

SELECT Id, CompanyName, account, amount, quantity
FROM MyTable
CROSS APPLY (
    SELECT account = 'part1_sales_amount', amount = part1_sales_amount, quantity = part1_sales_quantity
    UNION ALL
    SELECT account = 'part2_sales_amount', amount = part2_sales_amount, quantity = part2_sales_quantity
    UNION ALL
    SELECT account = 'part3_sales_amount', amount = part3_sales_amount, quantity = part3_sales_quantity
) AS AnotherData

您可以使用 apply :

select t.id, t.companyname, tt.amount, tt.qty
from table t cross apply
     ( values (t.part1_sales_amount, t.part1_sales_quantity),
              (t.part2_sales_amount, t.part2_sales_quantity),
              (t.part3_sales_amount, t.part3_sales_quantity),
               . . .    
     ) tt(amount, qty);

单反轴选择对应的数量栏:

declare @privot table
(
    id int,
    CompanyName varchar(20),
    part1_sales_amount money,
    part2_sales_amount money,   
    part3_sales_amount money,   
    part4_sales_amount money,
    part5_sales_amount money,
    part1_sales_quantity int,       
    part2_sales_quantity int,
    part3_sales_quantity int,
    part4_sales_quantity int,
    part5_sales_quantity int    

);

insert into @privot
(
    Id, CompanyName, 
    part1_sales_amount, part2_sales_amount, part3_sales_amount, part4_sales_amount, part5_sales_amount,
    part1_sales_quantity, part2_sales_quantity, part3_sales_quantity, part4_sales_quantity, part5_sales_quantity
)   
values
(1, 'FastCarsCo', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
(2, 'TastyCakeShop', 10, 20, 30, 40, 50, 60, 70, 80, 90, 100),
(3, 'KidsToys', 11, 21, 31, 41, 51, 61, 71, 81, 91, 101),
(4, 'FruitStall', 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000);

select 
    Id, CompanyName, replace(acc, '_amount', '') as acc, amount, 
    quantity=choose(/*try_cast ??*/replace(left(acc, charindex('_', acc)-1), 'part', ''), /*quantity columns*/part1_sales_quantity, part2_sales_quantity, part3_sales_quantity, part4_sales_quantity, part5_sales_quantity)    
FROM
(
SELECT *
    --Id, CompanyName, 
    --part1_sales_amount, part2_sales_amount, part3_sales_amount, part4_sales_amount, part5_sales_amount,
    --part1_sales_quantity ,part2_sales_quantity ,part3_sales_quantity , part4_sales_quantity, part5_sales_quantity
FROM @privot
) src
UNPIVOT
(
amount FOR acc IN (/*amount columns*/part1_sales_amount ,part2_sales_amount ,part3_sales_amount, part4_sales_amount, part5_sales_amount )
) pvt1;