如何在同一个SELECT语句中使用DISTINCT和ORDER BY?

问题描述 投票:88回答:12

执行以下语句后:

SELECT  Category  FROM MonitoringJob ORDER BY CreationDate DESC

我从数据库中获取以下值:

test3
test3
bildung
test4
test3
test2
test1

但我希望删除重复项,如下所示:

bildung
test4
test3
test2
test1

我尝试使用DISTINCT,但它在一个语句中不能与ORDER BY一起使用。请帮忙。

重要:

  1. 我尝试过: SELECT DISTINCT Category FROM MonitoringJob ORDER BY CreationDate DESC 它不起作用。
  2. CreationDate的订单非常重要。
sql sql-order-by distinct
12个回答
157
投票

问题是在ORDER BY中没有指定DISTINCT中使用的列。要做到这一点,你需要使用aggregate function进行排序,并使用GROUP BY使DISTINCT工作。

尝试这样的事情:

SELECT DISTINCT Category, MAX(CreationDate) 
FROM MonitoringJob 
GROUP BY Category 
ORDER BY MAX(CreationDate) DESC, Category

-2
投票

尝试下一步,但它对大数据无用......

SELECT DISTINCT Cat FROM (
  SELECT Category as Cat FROM MonitoringJob ORDER BY CreationDate DESC
);

-3
投票

它可以使用内部查询来完成

$query = "SELECT * 
            FROM (SELECT Category  
                FROM currency_rates                 
                ORDER BY id DESC) as rows               
            GROUP BY currency";

-4
投票
SELECT DISTINCT Category FROM MonitoringJob ORDER BY Category ASC

9
投票

Extended sort key columns

你想做什么不起作用的原因是因为logical order of operations in SQL,对于你的第一个查询,它是(简化的):

  • FROM MonitoringJob
  • SELECT Category, CreationDate即添加一个所谓的扩展排序键列
  • ORDER BY CreationDate DESC
  • SELECT Category即从结果中再次删除扩展排序键列。

因此,由于SQL标准扩展排序键列功能,完全可以通过SELECT子句中没有的内容进行排序,因为它是在幕后临时添加的。

So, why doesn't this work with DISTINCT?

如果我们添加DISTINCT操作,它将被添加到SELECTORDER BY之间:

  • FROM MonitoringJob
  • SELECT Category, CreationDate
  • DISTINCT
  • ORDER BY CreationDate DESC
  • SELECT Category

但是现在,使用扩展排序键列CreationDateDISTINCT操作的语义已经改变,因此结果将不再相同。这不是我们想要的,所以SQL标准和所有合理的数据库都禁止这种用法。

Workarounds

它可以使用标准语法进行仿真,如下所示

SELECT Category
FROM (
  SELECT Category, MAX(CreationDate) AS CreationDate
  FROM MonitoringJob
  GROUP BY Category
) t
ORDER BY CreationDate DESC

或者,只是简单地(在这种情况下),如Prutswonder所示

SELECT Category, MAX(CreationDate) AS CreationDate
FROM MonitoringJob
GROUP BY Category
ORDER BY CreationDate DESC

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


4
投票

如果不需要输出MAX(Cre​​ationDate) - 就像原始问题的例子那样 - 唯一的答案就是Prashant Gupta答案的第二个陈述:

SELECT [Category] FROM [MonitoringJob] 
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC

说明:您不能在内联函数中使用ORDER BY子句,因此在这种情况下,Prutswonder的答案中的语句不可用,您不能在其周围放置外部选择并丢弃MAX(Cre​​ationDate)部分。


2
投票

只需使用此代码,如果需要[Category]和[CreationDate]列的值

SELECT [Category], MAX([CreationDate]) FROM [MonitoringJob] 
             GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC

或者使用此代码,如果只想要[Category]列的值。

SELECT [Category] FROM [MonitoringJob] 
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC

你将拥有所有你想要的独特记录。


1
投票

2)CreationDate的订单非常重要

原始结果表明“test3”有多个结果......

很容易一直开始使用MAX去除Group By中的重复...并忘记或忽略底层问题是什么......

OP大概意识到使用MAX给了他最后一个“创建”并且使用MIN会给出第一个“创建”......


0
投票
if object_id ('tempdb..#tempreport') is not null
begin  
drop table #tempreport
end 
create table #tempreport (
Category  nvarchar(510),
CreationDate smallint )
insert into #tempreport 
select distinct Category from MonitoringJob (nolock) 
select * from #tempreport  ORDER BY CreationDate DESC

0
投票

通过子查询,它应该工作:

    SELECT distinct(Category) from MonitoringJob  where Category in(select Category from MonitoringJob order by CreationDate desc);

-1
投票

Distinct将按升序对记录进行排序。如果要按顺序排序使用:

SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC

如果要根据CreationDate字段对记录进行排序,则此字段必须位于select语句中:

SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC

-1
投票

你可以使用CTE:

WITH DistinctMonitoringJob AS (
    SELECT DISTINCT Category Distinct_Category FROM MonitoringJob 
)

SELECT Distinct_Category 
FROM DistinctMonitoringJob 
ORDER BY Distinct_Category DESC
© www.soinside.com 2019 - 2024. All rights reserved.