使用LEFT JOIN选择DISTINCT,在t-SQL中使用ORDERed BY

ahm*_*md0 9 sql t-sql sql-server distinct sql-order-by

我在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)
Run Code Online (Sandbox Code Playgroud)

选择相同类型的所有记录的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
Run Code Online (Sandbox Code Playgroud)

但它给了我一个错误:

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

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

Eri*_*ikE 6

通过未包含在DISTINCT项列表中的列对ORDER没有意义.

我们来看一个简单的场景.一,表FruitPerson:

Fruit  PersonName
-----  ------
Apple  Joe
Apple  Mary
Peach  Karen
Peach  Lance
Run Code Online (Sandbox Code Playgroud)

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

SELECT DISTINCT Fruit
FROM FruitPerson
ORDER BY PersonName;
Run Code Online (Sandbox Code Playgroud)

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

Fruit
-----
Apple
Peach
Run Code Online (Sandbox Code Playgroud)

但现在,问题是:引擎如何命令这两个值"Apple"和"Peach" PersonName哪个人名?每个水果有两个人!其姓名(或名称),准确地说,应该用它来决定是否Apple或者Peach是第一位的?

而是将您的查询重写为聚合:

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;
Run Code Online (Sandbox Code Playgroud)


Joe*_*orn 5

当您缩小单个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
Run Code Online (Sandbox Code Playgroud)

但是,如上所述,如果它匹配右侧表中的多个记录,则可以打开多次列出相同ID的可能性。