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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在同一个SELECT语句中使用DISTINCT和ORDER BY?相关的知识,希望对你有一定的参考价值。

执行以下语句后:

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

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

尝试这样的事情:

SELECT DISTINCT Category, MAX(CreationDate) 
FROM MonitoringJob 
GROUP BY Category 
ORDER BY MAX(CreationDate) DESC, Category
另一答案

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

SELECT DISTINCT Cat FROM (
  SELECT Category as Cat FROM MonitoringJob ORDER BY CreationDate DESC
);
另一答案

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

$query = "SELECT * 
            FROM (SELECT Category  
                FROM currency_rates                 
                ORDER BY id DESC) as rows               
            GROUP BY currency";
另一答案
SELECT DISTINCT Category FROM MonitoringJob ORDER BY Category ASC
另一答案

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

另一答案

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

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

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

另一答案

只需使用此代码,如果需要[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

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

另一答案

2)CreationDate的订单非常重要

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

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

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

另一答案
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
另一答案

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

    SELECT distinct(Category) from MonitoringJob  where Category in(select Category from MonitoringJob order by CreationDate desc);
另一答案

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

SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC

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

SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC
另一答案

你可以使用CTE:

WITH DistinctMonitoringJob AS (
    SELECT DISTINCT Category Distinct_Category FROM MonitoringJob 
)

SELECT Distinct_Category 
FROM DistinctMonitoringJob 
ORDER BY Distinct_Category DESC

以上是关于如何在同一个SELECT语句中使用DISTINCT和ORDER BY?的主要内容,如果未能解决你的问题,请参考以下文章

如何在同一 SQL 语句中使用 SELECT DISTINCT 和 CONCAT

Oracle Distinct子句

SQL SELECT DISTINCT 语句 用法

SQL SELECT DISTINCT 语句

二,本章讲解 SELECT DISTINCT 语句(distinct)

SQL SELECT DISTINCT 语句