【问题标题】:SQL - select distinct only on one column [duplicate]SQL - 仅在一列上选择不同的[重复]
【发布时间】:2013-12-22 18:02:40
【问题描述】:

我已经广泛搜索了这个问题的答案。我使用的是 Microsoft SQL Server,假设我有一个如下所示的表:

+--------+---------+-------------+-------------+
| ID     | NUMBER  | COUNTRY     | LANG        |
+--------+---------+-------------+-------------+
| 1      | 3968    | UK          | English     |
| 2      | 3968    | Spain       | Spanish     |
| 3      | 3968    | USA         | English     |
| 4      | 1234    | Greece      | Greek       |
| 5      | 1234    | Italy       | Italian     |

我想执行一个查询,它只选择唯一的“NUMBER”列(是第一行还是最后一行并不困扰我)。所以这会给我:

+--------+---------+-------------+-------------+
| ID     | NUMBER  | COUNTRY     | LANG        |
+--------+---------+-------------+-------------+
| 1      | 3968    | UK          | English     |
| 4      | 1234    | Greece      | Greek       |

这是如何实现的?

【问题讨论】:

标签: sql sql-server unique distinct


【解决方案1】:

既然你不在乎,我为每个数字选择了最大 ID。

select tbl.* from tbl
inner join (
select max(id) as maxID, number from tbl group by number) maxID
on maxID.maxID = tbl.id

查询说明

 select 
    tbl.*  -- give me all the data from the base table (tbl) 
 from 
    tbl    
    inner join (  -- only return rows in tbl which match this subquery
        select 
            max(id) as maxID -- MAX (ie distinct) ID per GROUP BY below
        from 
            tbl 
        group by 
            NUMBER            -- how to group rows for the MAX aggregation
    ) maxID
        on maxID.maxID = tbl.id -- join condition ie only return rows in tbl 
                                -- whose ID is also a MAX ID for a given NUMBER

【讨论】:

  • 无论如何,我并没有因此而投反对票,而是因为随着表变大,自联接到同一个表的聚合会成倍增加(就读取而言)。 Gordon's answer,除了更灵活之外,也更高效(或者至少不会更差)。
  • 多项式不是变得更昂贵吗?你是如何“成倍增长”的?
  • 我先回答了,然后顿悟了。无论如何,我也投票支持 Gordon 的答案,因为大多数重复项都使用相同的窗口方法。
  • 似乎对我不起作用,也许我用错了。如果人们在回答 SQL 问题时能够对查询中发生的事情给出某种解释,那就太好了。否则很难从答案中学习。
  • @RampantCreativeGroup 我添加了解释,希望对您有所帮助。
【解决方案2】:

您将使用以下查询:

SELECT * FROM [table] GROUP BY NUMBER;

其中[table] 是表的名称。

这为NUMBER 列提供了唯一的列表,但是其他列可能没有意义,具体取决于供应商的实现;也就是说,它们可能不会一起对应于特定的一行或多行。

【讨论】:

  • @Gedalya 这只能在 MySQL 中实现。它将在 SQL Server 中返回错误。
【解决方案3】:

解决此类问题的一个非常典型的方法是使用row_number()

select t.*
from (select t.*,
             row_number() over (partition by number order by id) as seqnum
      from t
     ) t
where seqnum = 1;

这比使用与最小 id 的比较更通用。例如,您可以使用order by newid() 获取随机行。您可以使用 where seqnum <= 2 选择 2 行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 2019-04-06
    • 1970-01-01
    • 2015-05-18
    • 2011-12-06
    相关资源
    最近更新 更多