【问题标题】:SQL Server Distinct, selects all rowsSQL Server Distinct,选择所有行
【发布时间】:2014-11-06 16:09:44
【问题描述】:

我已经看到了很多关于这个主题的问题和答案,但我很难理解我到底做错了什么。下面的查询获取了我需要的所有信息,但如果它有多行,当r_num 是相同的,并且每个 r_num 的 r_order 是相同的,那么每个 r_num 我只有一个结果。现在虽然这个调用给了我错误。有人可以向我解释Distinct是如何工作的,以及我如何使用它在这个查询中实现我的目标?

SELECT DISTINCT po_num, r_num, r_order, vendor, order_date, received_by, received_date FROM(
    SELECT p.id as po_num, r.id as r_num, r.rec_order as r_order, v.name as vendor, p.order_date, r.received_by, r.received_date
    FROM Parts.dbo.po as p INNER JOIN
    Parts.dbo.vendor as v ON v.id = p.vendor__id INNER JOIN
    Parts.dbo.receipts as r ON r.id = 'R-'+CAST(p.id AS varchar)
    GROUP BY p.id, r.id, r.rec_order, v.name, p.order_date, r.received_by, r.received_date) as tbl
GROUP BY r_num, r_order

这是我得到的错误

Msg 8120, Level 16, State 1, Line 1 Column 'tbl.po_num' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

【问题讨论】:

标签: sql-server


【解决方案1】:

除非您进行聚合,否则您不需要同时拥有 DISTINCT 和 GROUP BY。

SELECT DISTINCT po_num, r_num, r_order, vendor, order_date, received_by, received_date 
FROM
  (
    SELECT p.id as po_num, r.id as r_num, r.rec_order as r_order, v.name as vendor, p.order_date, r.received_by, r.received_date
    FROM Parts.dbo.po as p INNER JOIN
    Parts.dbo.vendor as v ON v.id = p.vendor__id INNER JOIN
    Parts.dbo.receipts as r ON r.id = 'R-'+CAST(p.id AS varchar)
    GROUP BY p.id, r.id, r.rec_order, v.name, p.order_date, r.received_by, r.received_date
  ) as tbl

如果您想获得不同的 r_num 和 r_order 值,则需要分组/仅选择这两列:

SELECT r_num, r_order
FROM
  (
    SELECT p.id as po_num, r.id as r_num, r.rec_order as r_order, v.name as vendor, p.order_date, r.received_by, r.received_date
    FROM Parts.dbo.po as p INNER JOIN
    Parts.dbo.vendor as v ON v.id = p.vendor__id INNER JOIN
    Parts.dbo.receipts as r ON r.id = 'R-'+CAST(p.id AS varchar)
    GROUP BY p.id, r.id, r.rec_order, v.name, p.order_date, r.received_by, r.received_date
  ) as tbl
GROUP BY r_num, r_order

或者,如果您的数据可以处理,请在额外列上使用聚合:

SELECT MAX(po_num) AS po_num, r_num, r_order, MAX(vendor) AS vendor -- etc.
FROM
  (
    SELECT p.id as po_num, r.id as r_num, r.rec_order as r_order, v.name as vendor, p.order_date, r.received_by, r.received_date
    FROM Parts.dbo.po as p INNER JOIN
    Parts.dbo.vendor as v ON v.id = p.vendor__id INNER JOIN
    Parts.dbo.receipts as r ON r.id = 'R-'+CAST(p.id AS varchar)
    GROUP BY p.id, r.id, r.rec_order, v.name, p.order_date, r.received_by, r.received_date
  ) as tbl
GROUP BY r_num, r_order

【讨论】:

  • 所以我唯一需要实际使用 DISTINCT 关键字的情况是,如果我想查找某些列的 SUM,或者可能出现多个结果的函数?
  • 不完全是:当您需要查找 SUM()(或任何其他聚合)时,请使用 GROUP BY。至于 DISTINCT,只有在查询中有多个完全相同的行时才需要它 - 它适用于返回的所有列。我通常发现在大多数情况下发生这种情况,我的 JOIN 做错了......
  • 啊,这很有道理,所以总结一下,在去其他任何地方之前,请确保我的 JOINS 正确且尽可能简洁。
  • 它当然不会受伤:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-16
相关资源
最近更新 更多