MariaDB (MySQL) "AVG" 无法使用 HAVING

MariaDB (MySQL) "AVG" not working with HAVING

我的问题是:为什么下面的两个 SQL 语句会产生不同的结果(我稍后会解释这两个语句。使用与 XAMPP 7.0.8 捆绑的 MariaDB 进行测试)

(1)

SELECT
stock_exchange_code,
summed
FROM (
   SELECT
     stock_exchange_code,
     summed
   FROM (
          SELECT
            STOCK_EXCHANGE_CODE,
            sum(SHARE_PRICE * SHARE_CNT) AS summed
          FROM LISTED_AT
          WHERE DATE_VALID = STR_TO_DATE('04-12-2015', '%d-%m-%Y')
          GROUP BY STOCK_EXCHANGE_CODE
        ) a) b
HAVING summed > avg(summed)

(2)

SELECT
stock_exchange_code,
summed
FROM (
   SELECT
     STOCK_EXCHANGE_CODE,
     sum(SHARE_PRICE * SHARE_CNT) AS summed
   FROM LISTED_AT
   WHERE DATE_VALID = STR_TO_DATE('04-12-2015', '%d-%m-%Y')
   GROUP BY STOCK_EXCHANGE_CODE
 ) a
WHERE summed > (SELECT avg(a.summed)
            FROM (SELECT
                    sum(SHARE_PRICE * SHARE_CNT) AS summed
                  FROM LISTED_AT
                  WHERE DATE_VALID = STR_TO_DATE('04-12-2015', '%d-%m-%Y')
                  GROUP BY STOCK_EXCHANGE_CODE) a)

这些查询的结果: (1)会给你一个空集(我不明白为什么) (2) 会给你2行,这是正确答案

2 Select 语句的解释:

  SELECT
     STOCK_EXCHANGE_CODE,
     sum(SHARE_PRICE * SHARE_CNT) AS summed
   FROM LISTED_AT
   WHERE DATE_VALID = STR_TO_DATE('04-12-2015', '%d-%m-%Y')
   GROUP BY STOCK_EXCHANGE_CODE

这是 Select 声明的一部分,总结了特定证券交易所的所有股票价值。 输出是:

BRX 122653.50

L&S 275000.00

MXK 500000.00

STU 140415.00

XETRA 254610.00

AVG(求和)= 258535.6

With 语句 (1) [这是我首先尝试的)我使用 select 来确定分组依据是全局的。现在来看,多了一个"serlect all columns by name",不过这里应该没关系。对于外部 select 我尝试应用 "HAVING" 子句。

我确实希望在特定日期的总价值 (=> "summed") 高于平均水平的所有证券交易所。据我了解,它应该计算全球平均值(上述 5 个证券交易所的 => )并对照它进行检查。

我不知道,为什么这不起作用。将 summed > avg(summed) 更改为 summed <> avg(summed) 会产生一行 (BRX 122653.50)。 summed > 0 结果全部 5 行 returned。 这就是为什么我认为平均值不适用于拥有而不是相反的原因。

(2) 这与第一个完全相同,用更明确的平均计算替换了 HAVING 子句。如您所见,有 2 个名称为 "a" 的子查询,两者都是相同的(第二个缺少 stock_exchange_code 字段。实际上,此查询与第一个相同,代码质量比第一个(重复)。

我的问题是:对我来说,这两个查询应该有相同的结果。为什么他们有不同的结果?

tl;博士

Average 或 having 子句似乎在 MySQL (MariaDB) 中不起作用。为什么从头开始的 2 SQL 语句不 return 相同?

聚合的使用会触发将整个 table 分组为一行。也就是说,HAVING summed > avg(summed) 使它成为一行,而不是行集合的某个子集。因此,#1 可能没有用。

在第二个查询中,将 avg(summed) 拼写为 SELECT ... 生成一个值,然后用于每一行。

看来您在两个查询中都有一个额外的 SELECTs 级别。

您可以使用 EXPLAIN SELECT ... 获取更多关于正在发生的事情的线索。