【问题标题】:Custom ORDER BY Explanation自定义 ORDER BY 说明
【发布时间】:2011-05-04 13:32:01
【问题描述】:

我前段时间发现了这个,从那以后就一直在使用它;但是,今天看它,我意识到我并不完全理解它为什么起作用。有人可以帮我解释一下吗?

ORDER BY  s.type!= 'Nails',
          s.type!= 'Bolts',
          s.type!= 'Washers',
          s.type!= 'Screws',
          s.type!= 'Staples',
          s.type!= 'Nuts', ...

如果我按 s.type 排序,它会按字母顺序排序。如果我使用上面的示例,它使用与行位置相同的顺序。我不明白的是使用!=。如果我使用 = 它以相反的顺序出现。我无法理解这个概念。

在我看来,使用 = 代替上面的 != 会将 Nails 放在首位,但事实并非如此,它会将它放在最后。我想我的问题是:为什么在这种情况下我必须使用!=,而不是 =?

【问题讨论】:

  • 所以,如果我有什么不明白的地方,即使我喜欢解决方案的优雅和简单,我也应该把手捂在耳朵上,重复“La, la, la”。我不喜欢这种方法;我宁愿学习新的东西并适应它。
  • 哇,好巧啊! :)

标签: postgresql sql-order-by


【解决方案1】:

对于array_position,它需要与您查询的类型相同。

例如:

select array_position(array['foo'::char,'bar','baz'::char], 'bar');
select array_position(array['foo'::char,'bar','baz'::char], 'baz'::char);

【讨论】:

    【解决方案2】:

    @Scott Bailey 提出了好主意。但从 PostgreSQL 9.5 开始,它可以更简单(您不必创建自定义函数)。只需使用array_position 函数:

    ORDER BY array_position(array['Nails','Bolts','Washers','Screws','Staples','Nuts'], s.type)
    

    【讨论】:

    • 在我的开发实例上试过了,很棒,生产仍在 9.3 .. 不太好
    • 这适用于Text 类型的列,我用character 类型的列尝试了这个,函数抛出了一个错误-希望这会有所帮助:)
    • 一个类似的问题也将有助于您可能需要做的任何投射:dba.stackexchange.com/questions/201837/…
    • 嘿 Daniil,我可以在 slick 中为 postgres 做同样的事情吗?
    • 不太确定,可能值得单独提问
    【解决方案3】:

    每个表达式都被评估为布尔值,0 表示假,1 表示真,并进行适当排序。即使这可行,但逻辑很难遵循(因此难以维护)。我使用的是一个在数组中查找值索引的函数。

    ORDER BY idx(array['Nails','Bolts','Washers','Screws','Staples','Nuts'], s.type)
    

    这更容易理解。钉子将首先分类,坚果最后分类。您可以在 Postgres sn-ps 存储库中查看如何创建 idx 函数。 http://wiki.postgresql.org/wiki/Array_Index

    【讨论】:

    • 应该是array_position
    • @EbenGeer 仅适用于 9.5 及更高版本
    • 那么在 9.5+ 中可以在这里简单地使用array_position 吗? @DarkMukke 我会将此添加到您的答案中。
    【解决方案4】:

    我从未见过,但它似乎有道理。

    起初它通过s.type != 'Nails' 订购。对于 type 列中包含 Nails 的每一行,这是 false。之后它按Bolts 排序。再次对于包含Bolts 作为type 的所有列,这将评估为假。以此类推。

    一个小测试显示falsetrue 之前排序。所以你有以下内容:首先你得到所有带有Nails的行,因为根据ORDER BY评估为falsefalse首先出现。其余行按第二个ORDER BY 标准排序。以此类推。

    类型 | != 指甲 | != 螺栓 | != 垫圈 '钉子' |假 |真实 |真的 '螺栓' |真实 |假 |真的 '垫圈' |真实 |真实 |错误的

    【讨论】:

    • 这纯粹是一个想法。但我假设它在 true 之前排序 false,因为它们尊重整数值 0 和 1,其中 0(false)在 1(true)之前。
    • 它在我投入使用的每台 SQL 服务器(PostgreSQL、MySQL 和 SQLite)上都非常有效!!
    猜你喜欢
    • 2019-04-23
    • 2010-11-20
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2012-01-06
    • 1970-01-01
    相关资源
    最近更新 更多