13

我在 SQL Server 2008 中有下表:

CREATE TABLE tbl (ID INT, dtIn DATETIME2, dtOut DATETIME2, Type INT)

INSERT tbl VALUES
(1, '05:00', '6:00', 1),
(2, '05:00', '7:00', 1),
(3, '05:01', '8:00', 1),
(4, '05:00', '8:00', 1),
(5, '05:00', '6:00', 2),
(6, '05:00', '7:00', 2)

选择相同类型的所有记录的 ID,具有相同的 dtIn 日期,按 stOut 升序排列:

SELECT DISTINCT tbl.id FROM tbl   
  LEFT JOIN tbl AS t1
  ON tbl.type = t1.type AND
     tbl.dtIn = t1.dtIn
  ORDER BY tbl.dtOut ASC

但这给了我一个错误:

如果指定了 SELECT DISTINCT,则 ORDER BY 项目必须出现在选择列表中

我尝试将 ORDER BY 放在不同的地方,但这一切似乎都不起作用。我在这里做错了什么?

4

5 回答 5

9

按未包含在 DISTINCT 项目列表中的列进行排序是没有意义的。

让我们使用一个简单的场景。首先,一个表FruitPerson

Fruit  PersonName
-----  ------
Apple  Joe
Apple  Mary
Peach  Karen
Peach  Lance

这是与您尝试执行的操作等效的查询:

SELECT DISTINCT Fruit
FROM FruitPerson
ORDER BY PersonName;

这个查询的结果ORDER BY是这样的:

Fruit
-----
Apple
Peach

但现在的问题是:引擎应该如何对“Apple”和“Peach”这两个值进行排序PersonName哪些人名?每个水果有两个人!确切地说,它应该使用哪个名称来决定是否ApplePeach出现?

相反,将您的查询重写为聚合:

SELECT Fruit, MinName = Min(PersonName) -- which name to order on
FROM FruitPerson
GROUP BY Fruit -- here's how you get your distinctness
ORDER BY MinName;
于 2012-07-20T21:22:56.520 回答
8

当您将其缩小到单个 id 时,您创建了每个 id 可能有多个dtOut关联的可能性。发生这种情况时,Sql Server 将如何知道使用哪个命令?

你可以试试:

SELECT t1.id
FROM tbl t1
LEFT JOIN  tbl t2 on t1.type = t2.type AND t1.dtIn = t2.dtIn
GROUP BY t1.id, t2.dtOut
ORDER BY t2.dtOut

但是,正如我上面提到的,如果它与右侧表格上的多个记录匹配,则可能会多次列出相同的 id。

于 2012-07-20T21:25:27.133 回答
0

当您使用“DISTINCT”关键字时,您只能使用 ORDER BY 子句中属于您的选择语句的那些列。所以你只能通过 tbl.id 订购

如果 id 是唯一的,则 DISTINCT 关键字没有任何意义,并且会导致性能下降,您可以将其删除。如果它们不是并且您决定在保持 DISTINCT 的同时选择 tbl.dtOut,则 tbl.id 和 tbl.dtOut 对可以为您提供具有相同 tbl.id 的多个条目,这可能是不希望的。

查看这篇文章 以了解可能的解决方法和解释为什么禁止此类查询。

于 2012-07-20T21:11:00.803 回答
0

您必须在选择列表中包含列 tbl.dtOut,以便它知道要订购什么。

SELECT DISTINCT tbl.id, tbl.dtOut FROM tbl   
  LEFT JOIN tbl AS t1
  ON tbl.type = t1.type AND
     tbl.dtIn = t1.dtIn
  ORDER BY tbl.dtOut ASC
于 2012-07-20T21:13:08.063 回答
0

您遇到此错误是因为您没有将 (tbl.dtOut) 放入选择列表中。

SELECT DISTINCT tbl.dtOut FROM tbl    
  LEFT JOIN tbl AS t1  
  ON tbl.type = t1.type AND  
     tbl.dtIn = t1.dtIn  
  ORDER BY tbl.dtOut ASC

会给你一个结果集(有 3 行),如果你也想要 id 字段那么

SELECT DISTINCT tbl.dtOut, tbl.ID FROM tbl      
  LEFT JOIN tbl AS t1  
  ON tbl.type = t1.type AND  
     tbl.dtIn = t1.dtIn  
  ORDER BY tbl.dtOut ASC  

(有 6 行,因为它给出了 id/date 字段的不同组合)

于 2012-07-20T23:32:15.287 回答