2016-08-08 34 views
0

Meine Frage funktioniert: Warum die beiden folgenden SQL-Anweisungen zu unterschiedlichen Ergebnissen führen (. Ich erkläre beide danach Getestet mit MariaDB gebündelte mit XAMPP 7.0.8)MariaDB (MySQL) „AVG“ nicht mit 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) 

Ergebnis dieser Abfragen: (1) geben Sie eine leere Menge (ich verstehe nicht, warum) (2) geben Ihnen 2 Zeilen, die die richtige Antwort

Erklärung der 2 Select-Anweisungen ist:

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 

Dies ist der Teil der Select-Anweisung, die alle Aktienwerte an einer bestimmten Börse fasst. Der Ausgang ist:

BRX 122653,50

L & S 275000,00

MXK 500000.00

STU 140415,00

XETRA 254610,00

und AVG (aufsummiert) = 258.535,6

Mit der Anweisung (1) [die ich zuerst ausprobiert habe] verwende ich eine Auswahl um sicherzustellen, dass die Gruppe global ist. Wenn man es jetzt anschaut, gibt es einen unnötigen "Alle Spalten mit Namen", das sollte hier keine Rolle spielen. Mit der äußeren Auswahl versuche ich die "HAVING" -Klausel anzuwenden.

Ich möchte alle Börsen, die summiert Wert (=> "summiert") an einem bestimmten Tag ist überdurchschnittlich. Soweit ich das verstehe, sollte er den globalen Durchschnitt (=> der 5 obigen Börsen) berechnen und dagegen abgleichen.

Ich weiß nicht, warum das nicht funktioniert. Das Ändern der summed > avg(summed) zu summed <> avg(summed) ergibt eine Zeile (BRX 122653.50). summed > 0 Ergebnisse in allen 5 Zeilen zurückgegeben. Das ist der Grund, warum ich denke, dass der Durchschnitt nicht mit dem Haben funktioniert und nicht umgekehrt.

(2) Das ist ziemlich das gleiche wie das erste, die HAVING-Klausel durch eine exlecit durchschnittliche Berechnung zu ersetzen. Wie Sie sehen können, gibt es 2 Unterabfragen mit dem Namen "a" und beide sind gleich (dem zweiten fehlt das Feld stock_exchange_code. Praktisch ist diese Abfrage identisch mit der ersten, mit schlechterer Codequalität als die erste (Duplizierung).

Meine Frage lautet:.? Für mich sind die 2-Abfragen ein identisches Ergebnis haben sollte, warum ein anderes Ergebnis haben sie

tl; dr

Durchschnitt oder Klausel scheint mit nicht in MySQL zu arbeiten (MariaDB) Warum werden die 2 SQL-Anweisungen von Anfang an nicht gleich zurückgegeben?

+0

Ich stimme zu HABEN ohne GROUP BY ist ungültig: http://stackoverflow.com/questions/6924896/having-without-group-by – SIDU

+0

@ SIDU: Möchten Sie sagen, dass HAVING ohne GROUP BY ungültig ist? Das würde keinen Sinn ergeben, da die Zählung und alle anderen Aggrifationsfunktionen ohne eine Gruppe funktionieren. ("Ohne eine Gruppe von" -> "Mit einer Gruppe, die ganze Tabelle"). Für mich ist es nicht wirklich sinnvoll, dass es diese Einschränkung mit der HAVING-Klausel geben sollte –

+0

Ich vermute, dass Sie Ihr Dilemma in weniger Zeilen Text kommunizieren könnten. – Strawberry

Antwort

2

Die Verwendung eines Aggregats löst die Gruppierung der gesamten Tabelle in einer Zeile aus. Das heißt, HAVING summed > avg(summed) bewirkt, dass es sich um eine Zeile handelt und nicht um eine Teilmenge der Zeilensammlung. Daher ist # 1 wahrscheinlich nicht nützlich.

In der zweiten Abfrage generiert die Schreibweise avg(summed) als SELECT ... einen Wert, der dann für jede Zeile verwendet wird.

Es scheint, dass Sie eine zusätzliche Ebene von SELECTs in beiden Abfragen haben.

Sie können EXPLAIN SELECT ... verwenden, um mehr Hinweise zu bekommen, was vor sich geht.