Сортировка сгенерированных столбцов ОБЪЕДИНЕНИЯ в динамической сводной таблице

#sql-server #pivot #coalesce

#sql-сервер #сводная #объединение

Вопрос:

Я хотел бы отсортировать столбцы, но я получаю следующую ошибку:

Предложение ORDER BY недопустимо в представлениях, встроенных функциях, производных таблицах, подзапросах и общих табличных выражениях, если также не указаны TOP, OFFSET или FOR XML.

Запрос years select возвращает их по порядку, но при обработке COALESCE функцией они перемешиваются.

Как я могу это предотвратить? Или, что еще лучше, контролировать сортировку?

ПРИМЕЧАНИЕ: сортировка работает, если я помещаю a TOP 10 в подзапрос. Супер странно…

 -- variables
DECLARE @sql AS varchar(max)
DECLARE @pivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @select_list AS varchar(max) -- Leave NULL for COALESCE technique

-- columns
SELECT -- top 10 makes the sorting work
    -- [2018], [2020], [2017], [2019] -- not ordered
    @pivot_list = COALESCE(@pivot_list   ', ', '')   '['   PIVOT_COLUMN   ']',
    @select_list = COALESCE(@select_list   ', ', '')   'ISNULL(['   PIVOT_COLUMN   '], 0) as ['   PIVOT_COLUMN   ']'
FROM (
    SELECT
        -- 2017, 2018, 2019, 2020 -- ordered
        cast(year(addate) as nvarchar(4)) as PIVOT_COLUMN
    FROM tHE_Move M
    where addate >= '01.01.2017'
    group by year(addate)
    --  order by year(addate) asc -- <-------------------------------------- doesn't work
) as PIVOT_COLUMNS

-- query
SET @sql = '
; WITH PivotData AS (
    select
        shop,
        y AS PIVOT_COLUMN,
        sum(revenueNoVAT) revenueNoVAT
    from (
        SELECT
            SS.acName2 shop,
            year(m.addate) y,
            MI.anPVVATBase revenueNoVAT
        FROM tHE_MoveItem MI
            JOIN tHE_Move M ON MI.acKey = M.acKey
            JOIN tHE_SetSubj SS ON M.acIssuer = SS.acSubject
        WHERE m.acDocType in (
            '   '''3210'''   ',
            '   '''3220'''   ',
            '   '''3230'''   ',
            '   '''3240'''   '
        )
    ) t1
    group by
        shop,
        y
)
SELECT shop, '   @select_list   '
FROM PivotData
    PIVOT (
        sum(revenueNoVAT)
        FOR PIVOT_COLUMN
        IN ('   @pivot_list   ')
    ) piv
order by shop desc
'

-- execution
EXEC (@sql)
 

Комментарии:

1. Вы пробовали эту UNLESS часть? Попробуйте Select Top 100 Percent и посмотрите, что у вас получится.

2. Как сообщает ошибка, вы не можете поместить an ORDER BY в подзапрос; поместите его вне него.

3. Интересно. Я добавил top 10 , и это работает. Добавление top(100) percent не выполняется. Что это за UNLESS часть, ничего не могу найти?

4. @Larnu Мне нужно отсортировать его, прежде чем он превратится в строку. Если я помещу его вне запроса, ему нечего сортировать. Кроме того, они сортируются в подзапросе. Они перемешиваются в процессе генерации строки.

5. Именно поэтому ORDER BY происходит переход во внешний запрос, где происходит прерывание присваивания. Лично, однако, я бы предложил STRING_AGG или FOR XML PATH над переменной, ссылающейся на себя.