简体   繁体   English

在 SQL 中对不同的合并列进行排序

[英]Sort Distinct Merged Columns in SQL

I have the following query:我有以下查询:

SELECT DISTINCT A + ' ' + B + ' ' + C AS 'ABC', D
FROM Table
ORDER BY A, B

This gives the following error message:这给出了以下错误消息:

ORDER BY items must appear in the select list if SELECT DISTINCT is specified.

I tried changing the ORDER By to this:我尝试将 ORDER By 更改为:

ORDER BY A, B, C 'ABC', D

And pretty much every variation there is of those possible combinations but the error remains.几乎所有这些可能的组合都有变化,但错误仍然存​​在。

So how can i get the distinct ABC and D first sorted by the A value, and after that the B value?那么我怎样才能得到不同的 ABC 和 D 首先按 A 值排序,然后按 B 值排序? (The C and D may remain unsorted and don't have to be Distinct seeing the ABC combination is already enough to indicate a unique value) (C 和 D 可能保持未排序并且不必是 Distinct 看到 ABC 组合已经足以表示唯一值)

EDIT:编辑:

Alternatively, is it possible to remove duplicates based on Columns A AND B without using DISTINCT?或者,是否可以在不使用 DISTINCT 的情况下根据列 A 和 B 删除重复项?

Since you have multiple letter words in each column, you will need to order using a window function in a derived table or CTE as shown below:由于每列中有多个字母单词,因此您需要使用派生表或 CTE 中的窗口函数进行排序,如下所示:

WITH ordering AS (
    SELECT A,
           B,
           C, 
           D,
           row_number() OVER (ORDER BY A,B,C,D) AS order_num
    FROM Table
)

SELECT DISTINCT A + ' ' + B + ' ' + C AS 'ABC', D
FROM ordering
ORDER BY order_num ASC

Edited: new approach based on the comment编辑:基于评论的新方法

You should use concat for string concatenation您应该使用 concat 进行字符串连接

SELECT DISTINCT CONCAT(A , ' ' , B , ' ', C) AS ABC, D
FROM Table
ORDER BY 1

Have you tried a group by?你有没有尝试过分组?

SELECT (A + ' ' + B + ' ' + C) AS 'ABC', D
FROM Table
ORDER BY A, B
GROUP BY (A + ' ' + B + ' ' + C), D

Use WITH clause :使用WITH 子句

with a AS (
  SELECT A, B, C, concat(A , ' ' , B, ' ', C) AS abc, D
FROM table1 order by A, B, C
)
select distinct abc FROM a ;



Do NOT use single quotes to delimit column names!不要使用单引号来分隔列名! Only use single quotes for string and date constants.仅对字符串和日期常量使用单引号。 If you had done this, your code would have just worked the first time:如果你这样做了,你的代码第一次就可以工作了:

SELECT DISTINCT A + ' ' + B + ' ' + C AS ABC, D
FROM Table
ORDER BY ABC;
SQL>create table t (id int, c1 varchar(3), c2 varchar(3));
SQL>insert into t values (1,'AX','B');
SQL>insert into t values (2,'AB','D');
SQL>insert into t values (3,'A','XB');
SQL>select concat(c1,c2) from t order by c1, c2;    

======
AXB
ABD
AXB

                  3 rows found

You can see above that row 2 ( ABD ) is sorted after one AXB row, and before the other AXB row, as the order by c1, c2 specifies.您可以在上面看到第 2 行 ( ABD ) 排序在一个AXB行之后,在另一个AXB行之前,如order by c1, c2指定的order by c1, c2

When you do SELECT DISTINCT , these two AXB rows will become only one row - which represents two separate rows in the table, one which is sorted before the ABD row, and one after the ABD row.当您执行SELECT DISTINCT ,这两个AXB行将仅成为一行 - 代表表中的两个单独的行,一个在ABD行之前排序,一个在ABD行之后排序。

You can't put the duplicate eliminated AXB both before and after ABD .您不能在ABD之前和之后放置重复消除的AXB That's why这就是为什么

ORDER BY items must appear in the select list if SELECT DISTINCT is specified.如果指定了 SELECT DISTINCT,则 ORDER BY 项必须出现在选择列表中。

Thanks to Brock's example of using "row_number() OVER" i thought of a way to do it myself using PARTISION BY.感谢 Brock 使用“row_number() OVER”的示例,我想到了一种使用 PARTISION BY 自己完成的方法。

WITH ordering AS 
(
    SELECT 
        A,
        B,
        C,
        D,
        row_number() OVER 
        (
            PARTITION BY
                A,
                B,
                C
            ORDER BY 
                A,
                B,
                C
        ) AS order_num
    FROM
        Table       
)
SELECT A + ' ' + B + ' ' + C AS 'ABC', D
FROM ordering
WHERE order_num = 1
ORDER BY A, B, C

This way, instead of using DISTINCT i use "row_number() OVER ( PARTITION BY" to give all records a number, with the duplicates getting an increased number. This allows me to filter on the order_num being 1 to remove all duplicates. This way i can simply order by the original 3 columns seeing Distinct is no longer a part of the query.这样,我不使用 DISTINCT,而是使用“row_number() OVER (PARTITION BY”)给所有记录一个编号,重复项的编号增加。这使我可以过滤 order_num 为 1 以删除所有重复项。这样我可以简单地按原始 3 列排序,看到 Distinct 不再是查询的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM