【问题标题】:How to use aggregate function in SQL clause that is outside of what you are selecting?如何在您选择的 SQL 子句中使用聚合函数?
【发布时间】:2021-11-25 05:50:44
【问题描述】:

抱歉标题凌乱。

我有一个数据库,其中包含不同的电影名称以及每部电影所属的每种类型。 我想选择“短片”类型的电影,其电影长度大于所有类型电影的平均长度。

流派用 1 表示是或 0 表示否。 到目前为止,这是我的选择语句:

SELECT MovieTitle, MovieLength
FROM MOVIES
WHERE GenreShort = 1
HAVING MovieLength > AVG(MovieLength)

我将如何将电影长度与所有电影的平均值进行比较,而不仅仅是“短”类型电影?

【问题讨论】:

  • 必须首先在单独的查询(“子查询”)中计算平均值。然后比较将在WHERE 子句中;没有GROUP BY 就不能有HAVING 子句。您没有以任何方式对短片进行分组;平均值是一个汇总的事实是一个单独的、不相关的问题。
  • 为每种类型创建一个新列是一种反模式。您应该有一个流派表列出所有流派,然后是一个链接表,其中包含一部电影所具有的每个流派的行。一旦完成查询和表在添加流派时不需要更改,它可能会节省空间,可以更容易地利用索引等。

标签: sql oracle aggregate having


【解决方案1】:

使用 子查询 获取所有电影的平均值,然后在比较中使用它,在使用 HAVING 子句之前还需要一个 GROUP BY。

SELECT MovieTitle, MovieLength 
FROM MOVIES 
WHERE GenreShort = 1 
GROUP BY MovieTitle, MovieLength 
HAVING MovieLength > (
                       SELECT AVG(MovieLength)
                       FROM MOVIES
                     );

或删除 HAVING 和 GROUP BY

SELECT MovieTitle, MovieLength 
FROM MOVIES 
WHERE GenreShort = 1 AND MovieLength > (
                       SELECT AVG(MovieLength)
                       FROM MOVIES
                     );

【讨论】:

  • 啊太棒了!我不知道那些存在。谢谢!
  • 非聚合查询中的“HAVING”子句?认真的吗?
  • @mathguy 您的评论是否意味着在某种程度上有所帮助?如果有,请详细说明。
  • 我的印象是与聚合子句的比较必须在 HAVING 子句中。
  • 您可以将HAVING 过滤器移动到WHERE 子句中并删除GROUP BY
【解决方案2】:

使用解析函数只从表中SELECT 一次:

SELECT MovieTitle,
       MovieLength
FROM   (
  SELECT MovieTitle,
         MovieLength,
         AVG(MovieLength) OVER () AS average_movielength
  FROM   MOVIES
  WHERE  GenreShort = 1
)
WHERE  movielength > average_movielength;

如果你想从表格中选择两次,那么:

SELECT MovieTitle,
       MovieLength 
FROM   MOVIES 
WHERE  GenreShort = 1 
AND    MovieLength > (SELECT AVG(MovieLength) FROM MOVIES);

db小提琴here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    相关资源
    最近更新 更多