首页 > 解决方案 > 我可以根据外部表对 SQL 中的排序列进行优先级排序吗

问题描述

我正在使用一个表,该表有几个列,这些列可能会根据用户设置进行排序。我试图想出一种避免动态 SQL 并将排序字符串存储在首选项表中的方法。

我正在使用的数据示例:

User   |  VIP  |  Date    | Priority  |  Location
---------------------------------------------------
 Jim   |   1   | 1/1/2019 |    0      |    105
 Joe   |   0   | 2/1/2019 |    0      |    104
 Jack  |   1   | 1/5/2019 |    1      |    105
 John  |   0   | 2/6/2019 |    1      |    106
 Jane  |   0   | 4/1/2019 |    1      |    105
 Jake  |   1   | 7/1/2019 |    0      |    105

排序表看起来像这样

Column   |  SortOrder |  Location
------------------------------------
 VIP     |      2     |    105
 Date    |      1     |    105
Priority |      -1    |    105
 VIP     |      1     |    104
 Date    |      2     |    104
Priority |      3     |    104
 VIP     |      1     |    106
 Date    |      -1    |    106
Priority |      2     |    106

我的查询将使用 location 作为 where 子句,因此我只会返回特定位置的值,但我想根据排序表中设置的值对该位置的数据进行排序。

-1 将是非活动排序,所以如果位置是 105,我想按日期排序,然后按 VIP。如果是 104,VIP,然后是日期,然后是优先级,如果是 106 VIP,那么优先级,不考虑日期。

我在想我也许可以做一些数学事情,但我很难想出一个算法。

我试图避免将 Date ASC、VIP ASC 硬编码到表中并通过动态 SQL 检索和应用它(虽然我确实有这个工作,但我希望有一个更好的、非动态的解决方案)。

有人有什么建议吗?

标签: sql-serversortingdynamic-sql

解决方案


你不能用数学做到这一点。

正如您所提到的,您可以使用动态 SQL,也可以使用一堆 CASES。

首先,您需要 PIVOT 或使用子查询或其他方法来为您可能排序的每个列获取虚拟 SortOrder 列。然后你可以做这样的事情:

ORDER BY CASE 
  WHEN [VipSortOrder]=1 THEN [VIP]
  WHEN [DateSortOrder]=1 THEN [Date]
  WHEN [PrioritySortOrder]=1 THEN [Priority]
END,
  CASE {Same for the 2's} etc...

如果是我,我个人会使用动态 sql。


推荐阅读