自定义ORDER BY函数SQL

bal*_*eak 2 sql t-sql

我对看起来像这样的自定义ORDER BY子句有要求

SQL自定义子句

SELECT * FROM example
ORDER BY 
CASE 
    WHEN name = 'I want this first' THEN 0
    WHEN name = 'I want this second' THEN 1
    WHEN name = 'We get the picture' THEN 2
    ELSE 99   END ASC
Run Code Online (Sandbox Code Playgroud)

但是,此case语句已经增长,我希望能够将排序顺序重用于其他查询。

我看到我的选择是

  1. 复制粘贴!
  2. 专门为此排序顺序添加到表中的另一列

在我看来,似乎我应该能够传递一个函数来执行排序逻辑。但是在SO和google上进行一些搜索后,我什么也找不到,并认为这也可能会帮助其他人。

Jea*_*rin 5

创建一个具有两列(名称,等级)的第二张表

SELECT * 
FROM example e INNER JOIN table2 t2 on e.name = t2.name
ORDER BY t2.rank ASC;
Run Code Online (Sandbox Code Playgroud)

第二张表将包含配对。

  • 我不鼓励这种方法,因为`JOIN`会影响查询的语义。 (2认同)
  • 以下查询可能不会产生相同的结果:`select e.*, count(*) over () from example`。 (2认同)

Gor*_*off 5

一种选择是 CTE:

with ordering as (
      select v.*
      from (values(1, 'val1'), (2, 'val2'), (3, 'val3')) v(priority, val)
    )
select e.*
from example e
order by (select priority from ordering o where o.val = e.name);
Run Code Online (Sandbox Code Playgroud)

我不鼓励你做一个明确的join,因为这可能会影响查询的语义。甲join过滤记录之前selectwheregroup by,和having条款被处理(逻辑上)。在order by仅使用在结果集(逻辑)的结果。

当然,您可以将 CTE 值存储在临时表或表变量中。那可能就是你所追求的。

另一种方法有点黑客,但在某些情况下有效。您可以将逻辑替换为:

order by charindex('[' + name + ']', '[name1][name2][name]')
Run Code Online (Sandbox Code Playgroud)

这假设所有名称都在列表中。并且该名称没有分隔符。这并不能直接解决您的问题,但您可以将字符串存储为代码块中的变量,甚至可以存储为表中的计算列。