2017-09-05 3 views
1

Ich versuche, eine Unterabfrage zu konfigurieren, habe aber einige Schwierigkeiten mit Aggregation/Gruppierung. Die Unterabfrage wählt eine Anzahl basierend auf dem Durchschnittswert aus. Wenn Sie jedoch die AVG(response) >= target-Bedingung in den WHERE-Block setzen, führt dies zu einem Fehler "Ungültige Verwendung der Gruppenfunktion". Platzieren die Bedingung in der MIT Block Werken Unterabfrage, mit der Ausnahme, dass es die Ziel Variable erfordert hat im SELECT Block mit dem COUNT erscheinen, die in einem Ergebnisfehler „Operanden sollte 1 Spalte (n) enthalten“. Eine Kopie der Abfrage befindet sich unten.MySQL Nested Query HAVING Feld

Ich bin vertraut mit verschachtelten Abfragen und Aggregatfunktionen, aber diese bestimmte Kombination weigert sich zu kooperieren. Es scheint, als sollte es ein Schlüsselwort für "wählen Sie dieses Feld für den Vergleich/HABEN, aber nicht zurückgeben", oder vielleicht bin ich nur falsche Formulierung der Abfrage. Leider wird dies von der BIRT-Reporting-Software durchgeführt, so dass ich (nach bestem Wissen und Gewissen) nicht einfach die Rohdaten erfassen und manuell aggregieren kann.

Die Abfrage (etwas für Klarheit geschnitten) ist unten:

SELECT 
    c.job_competency_id, 
    (
     SELECT 
      COUNT(ar1.assessment_result_id) 
     FROM 
      recent_assessment AS ra1, 
      assessment_result AS ar1, 
      client_job_competency AS jc1 
     WHERE 
      ar1.assessment_id = a.assessment_id 
      AND ra1.assessment_id = ar1.assessment_id 
      AND ar1.job_competency_id = jc1.job_competency_id 
      AND ar1.job_competency_id = c.job_competency_id 
      AND AVG(ar1.response) >= jc1.target 
     GROUP BY jc1.job_competency_id 
    ) AS n_meets 
FROM 
    recent_assessment AS ra, 
    assessment AS a, 
    assessment_result AS ar, 
    client_job_competency AS jc, 
    job_competency AS c, 
    master_competency AS mc 
WHERE 
    a.client_id = ? 
    AND ra.assessment_id = a.assessment_id 
    AND ar.assessment_id = a.assessment_id 
    AND c.job_competency_id = ar.job_competency_id 
    AND c.master_competency_id = mc.master_competency_id 
    AND jc.job_competency_id = c.job_competency_id; 

Falls es darauf ankommt, die alternative Unterabfrage ist hier:

(
     SELECT 
      COUNT(ar1.assessment_result_id), 
      jc1.target 
     FROM 
      recent_assessment AS ra1, 
      assessment_result AS ar1, 
      client_job_competency AS jc1 
     WHERE 
      ar1.assessment_id = a.assessment_id 
      AND ra1.assessment_id = ar1.assessment_id 
      AND ar1.job_competency_id = jc1.job_competency_id 
      AND ar1.job_competency_id = c.job_competency_id 
     GROUP BY jc1.job_competency_id 
     HAVING AVG(ar1.response) >= jc1.target 
    ) AS n_meets 

Wenn Sie bis hierher gelesen, danke für die Aufnahme ein Blick. Bitte lassen Sie mich wissen, wenn etwas geklärt werden muss. Hoffentlich habe ich irgendwo einen boneheaded Fehler gemacht.

+0

Dies ist eine korrelierte Unterabfrage, daher sollte immer 1 Zeile zurückgegeben werden. Warum musst du 'HAVING' verwenden, um es zu filtern? – Barmar

Antwort

0

Sie können keine Aggregationsfunktion in der WHERE-Klausel verwenden, da die Aggregation erst nach der Auswahl aller Zeilen verarbeitet wird. Dies ist der Fall in der WHERE-Klausel.

Um Ihr Problem mit HAVING zu lösen, bei dem Sie die zu vergleichende Spalte auswählen müssen, können Sie sie in eine andere Unterabfrageebene einfügen. Dann kann die äußere Abfrage nur die eine Spalte zurückgeben, die Sie in die SELECT Liste einfügen möchten.

(SELECT n_meets 
FROM (
    SELECT 
     COUNT(ar1.assessment_result_id) AS n_meets, 
     jc1.target 
    FROM 
     recent_assessment AS ra1, 
     assessment_result AS ar1, 
     client_job_competency AS jc1 
    WHERE 
     ar1.assessment_id = a.assessment_id 
     AND ra1.assessment_id = ar1.assessment_id 
     AND ar1.job_competency_id = jc1.job_competency_id 
     AND ar1.job_competency_id = c.job_competency_id 
    GROUP BY jc1.job_competency_id 
    HAVING AVG(ar1.response) >= jc1.target 
) AS x) AS n_meets