SQL Сервер создает таблицу Unpivot с условием где - PullRequest
1 голос
/ 01 мая 2020

Вот мой пример таблицы

---+-------------+------------------+------------------+------------------+--------------------+--------------------+--------------------+
| 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|
+---+-------------+------------------+------------------+------------------+--------------------+--------------------+--------------------+

Вот таблица вывода, которую я хочу

+---+-------------+------------------+------------------+------------------+
| 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. Я пробовал много вещей, но не правильный.

Примечание: в моей реальной базе данных здесь почти 200 столбцов, как те part1_sales_amount и part1_sales_quantity

Пожалуйста, помогите оценить.

Ответы [ 3 ]

4 голосов
/ 01 мая 2020

Вы можете использовать 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);
2 голосов
/ 01 мая 2020
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
1 голос
/ 01 мая 2020

Отключить и выбрать соответствующий столбец количества:

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;
...