Условное общее табличное выражение (CTE) в SQL

Я пытаюсь выбрать иерархию дерева категорий продуктов в SQL.

Мой код выглядит следующим образом. Я пытаюсь добиться динамического порядка сортировки, используя IF или Case When для параметра SortOrder.

Строка с комментариями должна быть активной, если @SortOrder равно 'sortorder'. Я попытался добавить вокруг него оператор If Else, но мне это не удалось...

Вы можете помочь?

CREATE PROCEDURE [dbo].[ProductCategory_SelectHierarchy]
    @SortOrder varchar(30)
AS
    SET NOCOUNT ON;

WITH Categories (Id,ParentId,SortOrder,RowOrder) as
(
        SELECT  parentCategory.Id,
                        parentCategory.ParentId,
                        parentCategory.SortOrder,
                        --cast(REPLACE(STR(parentCategory.SortOrder, 8), ' ', '0') as varchar(30)) 'RowOrder'
                        cast(CAST(DATEPART(YEAR, parentCategory.DateCreated) as varchar(4)) + 
                        CAST(DATEPART(MONTH, parentCategory.DateCreated) as varchar(2)) + 
                        CAST(DATEPART(DD, parentCategory.DateCreated) as varchar(2)) + 
                        CAST(DATEPART(HOUR, parentCategory.DateCreated) as varchar(2)) as varchar(50)) 'RowOrder'
        FROM        ProductCategories parentCategory
        WHERE       ParentId = 0

        UNION ALL

        SELECT  childCategories.Id,
                        childCategories.ParentId,
                        childCategories.SortOrder,
                        --cast(Categories.RowOrder + REPLACE(STR(childCategories.SortOrder, 8), ' ', '0') as varchar(30)) 'RowOrder'
                        cast(Categories.RowOrder + '/' + CAST(DATEPART(YEAR, childCategories.DateCreated) as varchar(4)) + 
                        CAST(DATEPART(MONTH, childCategories.DateCreated) as varchar(2)) + 
                        CAST(DATEPART(DD, childCategories.DateCreated) as varchar(2)) + 
                        CAST(DATEPART(HOUR, childCategories.DateCreated) as varchar(2)) as varchar(50)) 'RowOrder'
        FROM        ProductCategories childCategories
        JOIN        Categories
        ON          childCategories.ParentId = Categories.Id
)

SELECT pc.*, Categories.RowOrder 
FROM Categories 
INNER JOIN ProductCategories pc ON pc.Id = Categories.Id
ORDER BY RowOrder

person MartinHN    schedule 14.06.2010    source источник


Ответы (1)


Вы должны иметь возможность сортировать его так:

ORDER BY
    CASE
        WHEN @SortOrder = 'date_column' THEN CONVERT(VARCHAR(20), date_column, 120)
        WHEN @SortOrder = 'customer_id' THEN RIGHT(REPLICATE('0', 20) + CAST(customer_id AS VARCHAR(20)), 20)
        WHEN @SortOrder = 'name' THEN name
        ELSE sort_order
    END

Ключ в том, чтобы все ваши сортируемые столбцы (или выражения) имели один и тот же тип данных.

person Tom H    schedule 14.06.2010
comment
Не могу заставить его работать. Хотя ваш псевдокод не делает того, чего я пытаюсь достичь. Я хочу, чтобы @SortOrder был чем-то более статичным, например, «createdate», «salescount», «name» или «custom». Каждый случай должен приводить к различным операторам SQL. - person MartinHN; 14.06.2010
comment
Я только что отредактировал ответ теперь, когда у меня есть более четкое представление о том, что вы ищете. - person Tom H; 14.06.2010
comment
О, я должен сделать в порядке по пункту. Я изменил свой код, чтобы добавить все 4 столбца в набор данных, и сделать это в следующем порядке: ORDER BY CASE WHEN @SortOrder = 'NameSortedOrder' THEN Categories.NameSortedOrder WHEN @SortOrder = 'SalesCountOrder' THEN Categories.SalesCountOrder WHEN @SortOrder = 'DateCreatedOrder' THEN Categories.DateCreatedOrder ELSE Categories.SortOrder END - person MartinHN; 14.06.2010