SQL Server 2016 - Как сделать простую сводку - PullRequest
0 голосов
/ 21 сентября 2019

Я посмотрел много других примеров, но у них всегда есть какой-то AVG или SUM в их сводном запросе.И я не могу понять, как применить это в моем случае.Есть много примеров, но я не мог заставить его работать.Что не так с моим запросом?

Я просто хочу повернуть мою таблицу (запрос: SELECT LevelName, ParentNodeName from vOrgStructurePath where orgstructureid = 1545):

+---+-----------+----------------+
|   | LevelName | ParentNodeName |
+---+-----------+----------------+
| 1 | Level1    | Rough          |
+---+-----------+----------------+
| 2 | Level2    | Soft           |
+---+-----------+----------------+

К этому:

+---+--------+--------+
|   | Level1 | Level2 |
+---+--------+--------+
| 1 | Rough  | Soft   |
+---+--------+--------+

Вот моя попытка:

SELECT LevelName, ParentNodeName from vOrgStructurePath 
 PIVOT (LevelName for ParentNodeName IN ([Level1],[Level2])) as level
 where orgstructureid = 1545 

Но появляется эта ошибка:

Incorrect syntax near the keyword 'for'.

Любая помощь приветствуется, спасибо!

1 Ответ

1 голос
/ 21 сентября 2019

Все виды разворота требуют условной агрегации.Это единственный способ для вашей СУБД собрать несколько строк в одну.

Некоторые СУБД предоставляют специфичные для поставщика функции, которые реализуют сводную логику (SQL Server - одна из них, как и Oracle).Но они в основном просто синтаксический сахар поверх базовой идеи, которая всегда сводится к условной агрегации.

Я обычно выступаю против этих реализаций, специфичных для конкретного поставщика, поскольку прирост сложности запроса и большой выигрышпотеря переносимости (и удобочитаемости, если вы не являетесь экспертом в этом конкретном языке).

Вот стандартное решение для сводных данных, которое будет работать на большинстве, если не на всех СУБД:

SELECT
    MAX(CASE WHEN LevelName = 'Level1' THEN ParentNodeName END) as [Level1],
    MAX(CASE WHEN LevelName = 'Level2' THEN ParentNodeName END) as [Level2]
FROM vOrgStructurePath 
WHERE orgstructureid = 1545 

Вы можете легко обработать этот запрос сразу по нескольким orgstructureid, изменив его следующим образом:

SELECT
    orgstructureid,
    MAX(CASE WHEN LevelName = 'Level1' THEN ParentNodeName END) as [Level1],
    MAX(CASE WHEN LevelName = 'Level2' THEN ParentNodeName END) as [Level2]
FROM vOrgStructurePath 
GROUP BY orgstructureid

Это создает одну запись на orgstructureid вместе с Level1 и Level2 значения.

...