我有一个变量,其中包含如下所示的排序信息。排序信息可能会根据我将其保存在变量中的列而有所不同。
Declare @Sorting varchar(100) = 'AssetCode asc'
我正在使用此变量进行以下查询排序,但它不会根据排序详细信息对数据进行排序。
with _result as
(
select
ROW_NUMBER() over (order by @Sorting) as RowIndex,
*
from
@Assets
where
(@Keyword is null or (AssetCode like @Keyword
or DisplayName like @Keyword
or CategoryName like @Keyword
or SiteName like @Keyword
or BldgName like @Keyword
or SuiteName like @Keyword
or Location like @Keyword
or SerialVIN like @Keyword
or Barcode like @Keyword))
)
任何人都可以告诉我如何使用此变量与查询对结果进行排序?我会非常感激的。
答案 0 :(得分:3)
不使用动态SQL的替代方法:
-- order by flags, 1 = ASC, 0 = DESC, NULL = not order by this.
Declare @SortingByAssetCode bit = NULL;
Declare @SortingByDisplayName bit = 1;
Declare @SortingByCategoryName bit = NULL;
....
SELECT ...
...
ORDER BY
CASE WHEN SortingByAssetCode = 1 THEN AssetCode ELSE 0 END ASC,
CASE WHEN SortingByAssetCode = 0 THEN AssetCode ELSE 0 END DESC,
CASE WHEN SortingByDisplayName = 1 THEN DisplayName ELSE 0 END ASC,
CASE WHEN SortingByDisplayName = 0 THEN DisplayName ELSE 0 END DESC,
...
您无法动态更改字段的顺序(例如先按显示名称排序,然后再按资产代码排序)。
很可能它真的很慢而且真的很难维护。
答案 1 :(得分:1)
您可以使用简单的CASE
语句在没有动态SQL的情况下执行此操作。您可能希望调整变量以使用单独的ASC' DESC'变量,虽然您可以在紧要关系中解析现有变量。
SELECT
ROW_NUMBER() OVER (ORDER BY
CASE WHEN @order = 'DESC' THEN
CASE @Sorting
WHEN 'customer_id' THEN RIGHT(REPLICATE('0', 20) + CAST(customer_id AS VARCHAR(20)), 20)
WHEN 'first_name' THEN first_name
... etc.
ELSE NULL
END
ELSE NULL
END DESC,
CASE WHEN @order = 'DESC' THEN
CASE @Sorting
WHEN 'customer_id' THEN RIGHT(REPLICATE('0', 20) + CAST(customer_id AS VARCHAR(20)), 20)
WHEN 'first_name' THEN first_name
... etc.
ELSE NULL
END
ELSE NULL
END ASC
) as RowIndex,
*
FROM
@Assets
WHERE
请注意customer_id
必须如何按摩到一个字符串中,该字符串将正确排序为字符串。您需要对日期等进行相同操作,因为所有数据类型必须匹配。字符串是可以强制转换为所有数据类型的字符串(虽然从技术上讲,我应该可能使用NVARCHAR
)。
答案 2 :(得分:1)
如果要传递这样的变量,则需要使用多个case语句。给定变量的结构:
row_number() over ((case when @sorting = 'AssetCode asc' then AssetCode end) asc,
(case when @sorting = 'AssetCode desc' then AssetCode end) desc,
. . .
)
您应该可以为您的目的添加足够的这些表达式。关键是缺少else
条款。默认为NULL
,因此不匹配的值都相同。我认为没有理由将asc
/ desc
分隔为单独的变量。
另一种选择是动态SQL。动态SQL的优势在于优化器可以使用索引进行row_number()
计算。