【问题标题】:Using DISTINCT along with GROUP BY in SQL Server在 SQL Server 中使用 DISTINCT 和 GROUP BY
【发布时间】:2021-11-10 02:13:17
【问题描述】:

在 SQL 中同时使用 DISTINCT 和 GROUP BY 有什么目的吗?

下面是示例代码

SELECT DISTINCT Actors
FROM MovieDetails
GROUP BY Actors

有谁知道需要同时使用 DISTINCT 和 GROUP BY 以获得任何特定的期望结果的任何情况?

(DISTINCT和GROUP BY的一般用法分别理解)

【问题讨论】:

  • 可以在SELECT ..., COUNT(DISTINCT ...) FROM ... GROUP BY ...一起使用。在你的情况下这是没有意义的
  • 不,你可以放弃DISTINCT,这是多余的
  • group by 提供distinct 结果。添加它有什么用?想一想
  • 几周前,我浏览了一些文章,遇到了一些关于这个特殊用例的讨论。我再也找不到那篇文章了。因此,我想我会把它贴在这里!但我认为在几乎所有情况下都使用这两种方法是多余的!
  • 一个或另一个或两个你得到相同的查询计划和相同的结果。自己测试一下。

标签: sql-server group-by distinct


【解决方案1】:

使用DISTINCTGROUP BY 子句中删除重复的GROUPING SETS

在一个完全愚蠢的例子中,一般使用GROUPING SETS()(或者特别是特殊的分组集ROLLUP()CUBE()),你可以使用DISTINCT来再次删除分组集产生的重复值:

SELECT DISTINCT actors
FROM (VALUES('a'), ('a'), ('b'), ('b')) t(actors)
GROUP BY CUBE(actors, actors)

DISTINCT:

actors
------
NULL
a
b

没有DISTINCT

actors
------
a
b
NULL
a
b
a
b

但是,除了提出学术观点之外,您为什么还要这样做呢?

使用DISTINCT 查找唯一的聚合函数值

在一个不太牵强的例子中,您可能对DISTINCT 聚合值感兴趣,例如,有多少个不同重复的演员?

SELECT DISTINCT COUNT(*)
FROM (VALUES('a'), ('a'), ('b'), ('b')) t(actors)
GROUP BY actors

答案:

count
-----
2

使用DISTINCT 删除具有多个GROUP BY 列的重复项

当然,另一种情况是:

SELECT DISTINCT actors, COUNT(*)
FROM (VALUES('a', 1), ('a', 1), ('b', 1), ('b', 2)) t(actors, id)
GROUP BY actors, id

DISTINCT:

actors  count
-------------
a       2
b       1

没有DISTINCT

actors  count
-------------
a       2
b       1
b       1

有关更多详细信息,我已经写了一些博客文章,例如about GROUPING SETS and how they influence the GROUP BY operation,或about the logical order of SQL operations (as opposed to the lexical order of operations)

【讨论】:

  • 为了进一步举例,您还可以说 Select Distinct ... FROM ... GROUP BY... HAVING... 或 find distinct ... from table with some aggregate conditions
  • @BradD:我也想过同样的事情,但我想不出HAVING会改变什么。
  • 最后一个例子和 SELECT actors FROM (VALUES('a', 1), ('a', 1), ('b', 1), ('b', 2)) t(actors, id) GROUP BY actors 一样,为什么需要 distinct?
  • 查找具有多个 ID 的不同演员?还有其他方法可以到达那里,但例如清酒
  • @LukasEder 也许,但我更愿意使用SELECT actors, COUNT(DISTINCT id) FROM (VALUES('a', 1), ('a', 1), ('b', 1), ('b', 2)) t(actors, id) GROUP BY actors
【解决方案2】:

我会在 subselect 中分组,然后在 select 语句中取不同:

SELECT DISTINCT *
FROM (  SELECT Actors
        FROM MovieDetails
        GROUP BY Actors
    ) d

【讨论】:

  • 您能解释一下原因吗?该分组已经是唯一的。
【解决方案3】:

也许不是在你拥有它的上下文中,但你可以使用

SELECT DISTINCT col1,
PERCENTILE_CONT(col2) WITHIN GROUP (ORDER BY col2) OVER (PARTITION BY col1),
PERCENTILE_CONT(col2) WITHIN GROUP (ORDER BY col2) OVER (PARTITION BY col1, col3),
FROM TableA

您可以使用它来返回在单行中返回的不同级别的聚合。该用例适用于单个分组无法满足所有所需聚合的情况。

【讨论】:

  • OVER (PARTITION BY)?不是GROUP BY
  • 虽然请注意,您的主要条款中没有GROUP BY,所以从技术上讲,这不是被询问的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多