Using distinct on a column and doing order by on another column gives an error

前端 未结 11 2178
渐次进展
渐次进展 2021-02-05 14:43

I have a table: abc_test with columns n_num, k_str.

This query doesnt work:

    select distinct(n_num) from abc_test order by(k_str)

B

相关标签:
11条回答
  • 2021-02-05 15:20

    You are selecting the collection distinct(n_num) from the resultset from your query. So there is no actual relation with the column k_str anymore. A n_num can be from two rows each having a different value for k_str. So you can't order the collection distinct(n_num) by k_str.

    0 讨论(0)
  • 2021-02-05 15:22

    you can do

    select distinct top 10000 (n_num)  --assuming you won't have more than 10,000 rows                
    from abc_test order by(k_str)
    
    0 讨论(0)
  • 2021-02-05 15:25

    This approach is available in SQL server 2000, you can select distinct values from a table and order by different column which is not included in Distinct. But in SQL 2012 this will through you an error "ORDER BY items must appear in the select list if SELECT DISTINCT is specified."

    So, still if you want to use the same feature as of SQL 2000 you can use the column number for ordering(its not recommended in best practice).

    select distinct(n_num) from abc_test order by 1
    

    This will order the first column after fetching the result. If you want the ordering should be done based on different column other than distinct then you have to add that column also in select statement and use column number to order by.

    select distinct(n_num), k_str from abc_test order by 2
    
    0 讨论(0)
  • 2021-02-05 15:25

    When I got same error, I got it resolved by changing it as

    SELECT n_num 
    FROM(
       SELECT DISTINCT(n_num) AS n_num, k_str
       FROM abc_test
    ) as tbl
    ORDER BY tbl.k_str
    
    0 讨论(0)
  • 2021-02-05 15:30

    How do extended sort key columns

    The logical order of operations in SQL for your first query, is (simplified):

    • FROM abc_test
    • SELECT n_num, k_str i.e. add a so called extended sort key column
    • ORDER BY k_str DESC
    • SELECT n_num i.e. remove the extended sort key column again from the result.

    Thanks to the SQL standard extended sort key column feature, it is possible to order by something that is not in the SELECT clause, because it is being temporarily added to it behind the scenes prior to ordering, and then removed again after ordering.

    So, why doesn't this work with DISTINCT?

    If we add the DISTINCT operation, it would need to be added between SELECT and ORDER BY:

    • FROM abc_test
    • SELECT n_num, k_str i.e. add a so called extended sort key column
    • DISTINCT
    • ORDER BY k_str DESC
    • SELECT n_num i.e. remove the extended sort key column again from the result.

    But now, with the extended sort key column k_str, the semantics of the DISTINCT operation has been changed, so the result will no longer be the same. This is not what we want, so both the SQL standard, and all reasonable databases forbid this usage.

    Workarounds

    PostgreSQL has the DISTINCT ON syntax, which can be used here for precisely this job:

    SELECT DISTINCT ON (k_str) n_num
    FROM abc_test
    ORDER BY k_str DESC
    

    It can be emulated with standard syntax as follows, if you're not using PostgreSQL

    SELECT n_num
    FROM (
      SELECT n_num, MIN(k_str) AS k_str
      FROM abc_test
      GROUP BY n_num
    ) t
    ORDER BY k_str
    

    Or, just simply (in this case)

    SELECT n_num, MIN(k_str) AS k_str
    FROM abc_test
    GROUP BY n_num
    ORDER BY k_str
    

    I have blogged about SQL DISTINCT and ORDER BY more in detail here.

    0 讨论(0)
  • 2021-02-05 15:34

    My query doesn't match yours exactly, but it's pretty close.

    select distinct a.character_01 , (select top 1 b.sort_order from LookupData b where a.character_01 = b.character_01 )
    from LookupData a 
    where 
    Dataset_Name = 'Sample' and status = 200
    order by 2, 1
    
    0 讨论(0)
提交回复
热议问题