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

在执行以下语句之后:

SELECT  Category  FROM MonitoringJob ORDER BY CreationDate DESC

我从数据库中得到以下值:

test3
test3
bildung
test4
test3
test2
test1

但是我要把复制品移除,像这样:

bildung
test4
test3
test2
test1

我尝试使用 DISTINCT,但它在一个语句中无法与 ORDERBY 一起工作。请帮助。

重要提示:

  1. 我试过了:

    SELECT DISTINCT Category FROM MonitoringJob ORDER BY CreationDate DESC
    

    没用的。

  2. 通过 CreationDate 订购是非常重要的。

425093 次浏览
SELECT DISTINCT Category FROM MonitoringJob ORDER BY Category ASC

问题是 ORDER BY中使用的列没有在 DISTINCT中指定。为此,需要使用 聚合函数进行排序,并使用 GROUP BY使 DISTINCT工作。

试试这样:

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

可区分的将按升序对记录进行排序。如果要按 desc 顺序进行排序,请使用:

SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC

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

SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC

只要使用这个代码,如果您想要的值[类别]和[创建日期]列

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

或使用此代码,如果您只想要[类别]列的值。

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

你想要什么都可以。

下一个试试,但是对于大数据来说没有用..。

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

2)按照 CreationDate 订购非常重要

最初的结果表明,“ test3”有多个结果..。

这是非常容易开始使用 MAX 所有的时间删除重复组的... 而忘记或忽略什么是潜在的问题..。

OP 大概意识到使用 MAX 给他最后一个“创建”,使用 MIN 给第一个“创建”..。

可以使用内部查询来完成,如下所示

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

如果不需要 MAX (CreationDate)的输出——就像最初问题的例子一样——唯一的答案是 Prashant Gupta 回答的第二个陈述:

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

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

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

你可以使用 CTE:

WITH DistinctMonitoringJob AS (
SELECT DISTINCT Category Distinct_Category FROM MonitoringJob
)


SELECT Distinct_Category
FROM DistinctMonitoringJob
ORDER BY Distinct_Category DESC

扩展的排序键列

你想要做的事情之所以不起作用,是因为 SQL 中操作的逻辑顺序,正如我在这篇博客文章中所阐述的,对于你的第一个查询,它是(简化的) :

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

因此,由于 SQL 标准 扩展排序键列扩展排序键列特性,完全可以按照不在 SELECT子句中的内容进行排序,因为它是在幕后临时添加的。

那么,为什么这个在 DISTINCT上不起作用呢?

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

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

但是现在,对于 extended sort key column CreationDateDISTINCT操作的语义已经改变,因此结果将不再相同。这不是我们想要的,因此 SQL 标准和所有合理的数据库都禁止这种使用。

变通方法

可以使用以下标准语法对其进行模拟

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

或者,仅仅是(在这种情况下) ,如 普鲁斯旺德所示

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

我在博客中更详细地介绍了 SQL DISTINCT 和 ORDER BY。

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

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

我们可以通过选择子查询来实现这一点

下面是问题所在:

SELECT * FROM (
SELECT DISTINCT Category FROM MonitoringJob
) AS Tbl
ORDER BY Tbl.CreationDate DESC