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

时间:2011-03-22 12:55:02

标签: sql sql-order-by distinct

执行以下声明后:

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的订单非常重要。

12 个答案:

答案 0 :(得分:153)

问题是ORDER BY中未指定DISTINCT中使用的列。为此,您需要使用aggregate function进行排序,并使用GROUP BY使DISTINCT正常工作。

尝试这样的事情:

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

答案 1 :(得分:7)

扩展的排序键列

您要执行的操作无效的原因是因为logical order of operations in SQL,对于您的第一个查询,它是(简体):

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

因此,由于采用了SQL标准的扩展的排序键列功能,完全可以用SELECT子句中没有的东西进行排序,因为它是暂时添加到它在幕后。

那么,为什么DISTINCT不能使用?

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

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

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

解决方法

可以使用以下标准语法进行仿真

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

答案 2 :(得分:4)

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

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

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

答案 3 :(得分: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

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

答案 4 :(得分:0)

  

2)CreationDate的订单非常重要

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

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

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

答案 5 :(得分: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

答案 6 :(得分:0)

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

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

答案 7 :(得分:-1)

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

SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC

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

SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC

答案 8 :(得分:-1)

您可以使用CTE:

WITH DistinctMonitoringJob AS (
    SELECT DISTINCT Category Distinct_Category FROM MonitoringJob 
)

SELECT Distinct_Category 
FROM DistinctMonitoringJob 
ORDER BY Distinct_Category DESC

答案 9 :(得分:-2)

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

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

答案 10 :(得分:-3)

可以使用内部查询来完成这样的

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

答案 11 :(得分:-4)

SELECT DISTINCT Category FROM MonitoringJob ORDER BY Category ASC