Данные SQL Pivot в одну строку на элемент
У меня есть такая таблица с именем продукта, указанным несколько раз для каждого LAY:
NAME | LAYER | TYPE | DEPTH
-------------------------------------
32_42_1 | LAY_1 | A | 99.4
32_42_1 | LAY_2 | D | 427.2
32_42_1 | LAY_3 | X | 120.4
32_42_1 | LAY_4 | B | 27
32_42_2 | LAY_1 | A | 150.4
32_42_2 | LAY_2 | D | 427.2
32_42_2 | LAY_3 | X | 121.4
32_42_2 | LAY_4 | C | 40
32_42_3 | LAY_1 | F | 80.97
32_42_3 | LAY_2 | Y | 300.2
32_42_3 | LAY_3 | C | 123.4
32_42_3 | LAY_4 | C | 120
Мне нужно, чтобы каждое ИМЯ имело только одну строку, и поэтому его нужно вращать так:
NAME | LAY_1_TYPE | LAY_1_DEPTH | LAY_2_TYPE | LAY_2_DEPTH | LAY_3...
--------------------------------------------------------------------
32_42_1| A | 99.4 | D | 427.2 | ...
32_42_2| A | 150.4 | D | 427.2 | ...
32_42_3| F | 80.7 | Y | 300.2 | ...
Я нашел много похожих решений, и хотя некоторые из них были близки, я не смог изменить код в соответствии со своими потребностями.
Это то, что я до сих пор:
PIVOT
(
MAX(TYPE) For LAYER In (LAY_1,LAY_2,LAY_3,LAY_4,LAY_5)
) piv
Но это сводит только один столбец и не сжимает данные в одну строку для каждого "имени"
Любая помощь будет оценена!
1 ответ
Решение
Сводка с более чем одним столбцом лучше сделать с условным агрегированием:
DECLARE @tbl TABLE (NAME VARCHAR(100),LAYER VARCHAR(100),TYPE VARCHAR(100),DEPTH DECIMAL(10,4));
INSERT INTO @tbl VALUES
('32_42_1','LAY_1','A','99.4')
,('32_42_1','LAY_2','D','427.2')
,('32_42_1','LAY_3','X','120.4')
,('32_42_1','LAY_4','B','27')
,('32_42_2','LAY_1','A','150.4')
,('32_42_2','LAY_2','D','427.2')
,('32_42_2','LAY_3','X','121.4')
,('32_42_2','LAY_4','C','40')
,('32_42_3','LAY_1','F','80.97')
,('32_42_3','LAY_2','Y','300.2')
,('32_42_3','LAY_3','C','123.4')
,('32_42_3','LAY_4','C','120');
SELECT t.NAME
,MAX(CASE WHEN t.LAYER='LAY_1' THEN t.TYPE END) AS Type1
,MAX(CASE WHEN t.LAYER='LAY_1' THEN t.DEPTH END) AS Depth1
,MAX(CASE WHEN t.LAYER='LAY_2' THEN t.TYPE END) AS Type2
,MAX(CASE WHEN t.LAYER='LAY_2' THEN t.DEPTH END) AS Depth2
,MAX(CASE WHEN t.LAYER='LAY_3' THEN t.TYPE END) AS Type3
,MAX(CASE WHEN t.LAYER='LAY_3' THEN t.DEPTH END) AS Depth3
,MAX(CASE WHEN t.LAYER='LAY_4' THEN t.TYPE END) AS Type4
,MAX(CASE WHEN t.LAYER='LAY_4' THEN t.DEPTH END) AS Depth4
FROM @tbl AS t
GROUP BY t.NAME;
Результат
+---------+-------+----------+-------+----------+-------+----------+-------+----------+
| NAME | Type1 | Depth1 | Type2 | Depth2 | Type3 | Depth3 | Type4 | Depth4 |
+---------+-------+----------+-------+----------+-------+----------+-------+----------+
| 32_42_1 | A | 99.4000 | D | 427.2000 | X | 120.4000 | B | 27.0000 |
+---------+-------+----------+-------+----------+-------+----------+-------+----------+
| 32_42_2 | A | 150.4000 | D | 427.2000 | X | 121.4000 | C | 40.0000 |
+---------+-------+----------+-------+----------+-------+----------+-------+----------+
| 32_42_3 | F | 80.9700 | Y | 300.2000 | C | 123.4000 | C | 120.0000 |
+---------+-------+----------+-------+----------+-------+----------+-------+----------+