【问题标题】:Sort by the largest value across multiple columns按多列中的最大值排序
【发布时间】:2018-06-21 03:33:06
【问题描述】:

通过查看每行中的最大列值对查询进行排序的最有效方法是什么?

例如:

Dan | 5 | 0 | 3
Moe | 0 | 9 | 2
Joe | 3 | 3 | 8

排序此数据集应返回:Moe、Joe、Dan

我的数据集比上面的更复杂,所以我试图避免子查询与最大分组的任何组合。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    你可以使用CROSS APPLY:

    SELECT *
    FROM tab t
    CROSS APPLY (SELECT MAX(col) c FROM (VALUES(t.col1),(t.col2),(t.col3)) sub(col)) s
    ORDER BY s.c DESC;
    

    DBFiddle Demo

    输出:

    ┌──────┬──────┬──────┬──────┬───┐
    │ name │ col1 │ col2 │ col3 │ c │
    ├──────┼──────┼──────┼──────┼───┤
    │ Moe  │    0 │    9 │    2 │ 9 │
    │ Joe  │    3 │    3 │    8 │ 8 │
    │ Dan  │    5 │    0 │    3 │ 5 │
    └──────┴──────┴──────┴──────┴───┘
    

    编辑

    很好的答案。我不认为有办法对任意数量的列(没有 dsql)执行此操作吗?

    有一种不用动态SQL的方法:

    SELECT DISTINCT t.*, c.s
    FROM tab t
    CROSS APPLY (VALUES(CAST((SELECT t.* for XML RAW) AS xml))) B(XMLData)
    CROSS APPLY (SELECT MAX(a.value('.','INT') ) s
                 FROM B.XMLData.nodes('/row')  AS C1(n)
                 CROSS APPLY C1.n.nodes('./@*') AS C2(a)
                 WHERE a.value('local-name(.)','varchar(100)') LIKE 'col%'
                         -- filtering based on name
                         -- it is also possible to JOIN and filter 
                         -- based on metadata like sys.columns
                   ) C
    ORDER BY s DESC;
    

    DBFiddle Demo

    【讨论】:

    • 很好的答案。我不认为有办法对任意数量的列(没有 dsql)执行此操作吗?
    • @Xedni 嗯,很好的问题,我想 XML 技巧是可能的。类似于SELECT rows that have specified values in one of the columns
    • @Xedni 是的,这是可能的。请查看我的演示
    • 蒂卢卡斯。我必须记住这个
    • 你想要:CREATE VIEW my_view AS SELECT * FROM tab t CROSS APPLY (SELECT MAX(col) c FROM (VALUES(t.col1),(t.col2),(t.col3)) sub(col)) s 然后SELECT * FROM my_view ORDER BY c DESC
    【解决方案2】:

    我几乎从不对数据库进行排序。 在这种情况下,排序很复杂,而且比您提供的模型更复杂,我通常将数据从数据库中取出并在代码中进行排序。

    当我这样做时,我总是会因为性能的提高而得到回报。 在内存中排序 8000000 行比在数据库中便宜得多。 由于您的数据模型很复杂,因此编写算法对其进行排序比编写 sql 更灵活 - 您可以编写能够抵抗架构更改的代码,并且将继续遵守您的规则。

    【讨论】:

      猜你喜欢
      • 2018-10-21
      • 2013-05-04
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 2015-03-05
      • 2018-05-15
      相关资源
      最近更新 更多