2016-08-08 5 views
0

Мой вопрос: Почему следующие два SQL заявления дают разные результаты (. Я объясняю, как впоследствии Испытано с MariaDB bundeled с XAMPP 7.0.8)MariaDB (MySQL) «AVG» не работает с HAVING

(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 
    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 

Это часть Выберите заявление, которое суммирует все значения акций на определенной фондовой бирже. Выход:

BRX 122653,50

L & S 275000.00

MXK 500000.00

СТЮ 140415,00

XETRA 254610,00

и AVG (суммарное) = 258535,6

С заявлением (1) [которое я пробовал первым) Я использую select around, чтобы быть уверенным, что группа by global. Глядя на это сейчас, есть один ненужный «набор всех столбцов по имени», это не имеет значения. При внешнем выборе я пытаюсь применить предложение «HAVING».

Я хочу, чтобы все фондовые биржи, суммированные значения (=> "summed") в определенный день, были выше среднего. Насколько я понимаю HAVING, он должен рассчитать глобальную среднюю (=> из 5 бирж выше) и проверить на это.

Я не знаю, почему это не работает. Изменение summed > avg(summed) на summed <> avg(summed) приводит к одной строке (BRX 122653.50). summed > 0 результат во всех 5 строках. Вот почему я думаю, что средний не работает с наличием, а не наоборот.

(2) Это совершенно то же самое, что и первое, заменив предложение HAVING более усредненным расчетом. Как вы можете видеть, есть два подзапроса с именем «a», и оба они одинаковы (второе не имеет поля stock_exchange_code. Практически этот запрос идентичен первому, с худшим качеством кода, чем первый (дублирование).

Мой вопрос:.? для меня 2 запросы должны иметь одинаковый результат Почему они имеют различный результат

ТЛ; Др

Среднее или имеющие положение, кажется, не работает в MySQL (MariaDB). Почему два оператора SQL с самого начала не возвращают то же самое?

+0

Я согласен HAVING без GROUP BY недействителен: http://stackoverflow.com/questions/6924896/having-without-group-by – SIDU

+0

@SIDU: Вы хотите сказать, что HAVING без GROUP BY недействителен? Это не имеет смысла, поскольку счет и все другие функции аггрефикации работают без группы. («Без группы» -> «С одной группой, всей таблицей»). Для меня не имеет смысла, что это ограничение должно быть связано с предложением HAVING –

+0

Я подозреваю, что вы могли бы сообщить свое затруднение в меньшем количестве строк текста. – Strawberry

ответ

2

Использование совокупных триггеров, объединяющих всю таблицу в одну строку. То есть HAVING summed > avg(summed) заставляет его быть одной строкой, а не некоторым подмножеством коллекции строк. Следовательно, # 1, вероятно, не полезно.

Во втором запросе, определяющем avg(summed), как SELECT ... генерирует одно значение, которое затем используется для каждой строки.

Кажется, что у вас есть дополнительный уровень SELECTs в обоих запросах.

Вы можете использовать EXPLAIN SELECT ..., чтобы узнать больше о том, что происходит.