Die Unterabfrage kann keine Spalte aus dem Join der Superabfrage finden


7

Ich habe Probleme mit SQL: Grundsätzlich versuche ich, eine Ergebnismenge zurückzubekommen, die eine Summe ALLER Fragen enthält, die an Mitarbeiter gestellt wurden (gruppiert nach Unternehmen), und füge auch die "onetime_items" hinzu, die manuell Elemente in a hinzugefügt werden andere Tabelle.

Ich habe derzeit diese SQL-Anweisung (ich verwende MySQL):

SELECT 
CONCAT_WS(
    ', ', count(DISTINCT CONCAT(emailaddress, '_', e.id)),
    (
        SELECT GROUP_CONCAT(items SEPARATOR '; ') as OneTimeItems
        FROM ( 
            SELECT CONCAT_WS(
                ': ', oi.item_name, SUM(oi.item_amount)
            ) items 
            FROM onetime_item oi 
            WHERE oi.company_id = e.company_id
            AND oi.date BETWEEN '2015-12-01'
            AND LAST_DAY('2015-12-01') 
            GROUP BY oi.item_name 
        ) resulta
    )
) as AllItems,
e.id,
LEFT(e.firstname, 1) as voorletter,
e.lastname
FROM question q 
LEFT JOIN employee e ON q.employee_id = e.id 
WHERE 1=1 
AND YEAR(created_at) = '2015'
AND MONTH(created_at) = '12' 
GROUP BY e.company_id

Jetzt bekomme ich folgenden Fehler:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.company_id' in where clause

Die verwendeten Daten sind Dummy-Daten und die 1 = 1 am unteren Punkt der where-Klausel, da ich die where-Anweisung basierend auf Benutzereingabewerten generiere.

Alle Spalten sind im Tabellenmitarbeiter vorhanden, und der linke Join funktioniert (ich habe versucht, eine ID manuell einzugeben, anstatt die Spaltenreferenz zu verwenden, und es hat funktioniert, ich habe das richtige Ergebnis zurückerhalten).

Es tut mir auch leid, aber ich darf kein Tabellenschema oder irgendetwas im Zusammenhang mit der DB-Struktur online veröffentlichen.

Irgendeine Idee, warum der Verweis auf e.company_id fehlschlägt?

EDIT: Dies ist die Ergebnismenge, die ich brauche:

5, Het is je verjaardag: 1; Skivakantie: 1; Telefonische leadvergoeding: 8

Die Konstruktion ist wie folgt: 5 = führt durch Komma getrennt, um den Rest zu erhalten. Leads sind die eindeutige Kombination aus der Fragentabelle, und der Rest der Ergebnisse wird aus onetime_items erstellt.

BEARBEITEN 2 : SQL-Geige wirft immer wieder einen Fehler auf mich, also werde ich nur eine kleine erfundene Datenbank mit ein paar erfundenen Daten veröffentlichen: http://pastebin.com/cCveVtGr


2
Wahrscheinlich, weil es zu tief verschachtelt ist
Philᵀᴹ

@Phil Irgendeine Idee, wie die Referenz funktioniert?
FMashiro

GROUP BYFunktioniert "nach" Auswahl (stark vereinfacht), sodass manchmal die nicht ausgewählten Spalten nicht angezeigt werden (kann von Optimierungen abhängen, die der Planer für Ihre Abfrage usw. vornimmt). Also , e.company_idnachher hinzufügen e.lastname.
Jkavalik

@jkavalik Ich habe versucht, es der SQL hinzuzufügen und auszuführen, aber es gibt mir immer noch den Fehler "# 1054 - Unbekannte Spalte 'e.company_id' in 'where-Klausel'"
FMashiro

@ FMashiro ah, sorry, ich wurde durch einen anderen Fehler abgelenkt, den ich einmal bekam ..
jkavalik

Antworten:


4

Die Ursache des Problems wurde von @Phil in den Kommentaren identifiziert :

Wahrscheinlich, weil es zu tief verschachtelt ist

Sie haben 2 Verschachtelungsebenen und die Referenz der Tabelle ekann diese 2 Ebenen in MySQL nicht "durchschauen".

Korrelierte Inline-Unterabfragen können normalerweise in abgeleitete Tabellen konvertiert und dann LEFTmit den anderen Tabellen in der FROMKlausel verknüpft werden. Sie müssen jedoch in unkorrelierte Tabellen umgewandelt werden (in MySQL. In anderen DBMS können Sie einen LATERALJoin oder ähnliches verwenden OUTER APPLY.

Ein erstes Umschreiben, um die Arbeit zu erledigen:

SELECT 
    CONCAT_WS(
        ', ', count(DISTINCT CONCAT(q.emailaddress, '_', e.id)),
        dv.OneTimeItems
    ) as AllItems,
    e.id,
    LEFT(e.firstname, 1) as voorletter,
    e.lastname
FROM question q 
LEFT JOIN employee e ON q.employee_id = e.id 
LEFT JOIN
    (
        SELECT company_id,
               GROUP_CONCAT(items SEPARATOR '; ') AS OneTimeItems
        FROM ( 
            SELECT oi.company_id,
                   CONCAT_WS(
                ': ', oi.item_name, SUM(oi.item_amount)
            ) items 
            FROM onetime_item oi 
            WHERE oi.date BETWEEN '2015-12-01'
                              AND LAST_DAY('2015-12-01') 
            GROUP BY oi.company_id, oi.item_name 
        ) resulta
        GROUP BY company_id
    ) AS dv
    ON dv.company_id = e.company_id
WHERE 1=1 
AND YEAR(q.created_at) = '2015'
AND MONTH(q.created_at) = '12' 
GROUP BY e.company_id ;

In SQLfiddle testen .


Nicht im Zusammenhang mit den Problemkommentaren:

  • Es gibt GROUP BY e.company_idwährend die selectListe hat e.id, LEFT(e.firstname, 1), e.lastname. All dies führt zu willkürlichen Ergebnissen eines (mehr oder weniger zufälligen) Mitarbeiters für jedes Unternehmen - oder sogar in äußerst seltenen Fällen zu willkürlichen Ergebnissen von 2 oder 3 verschiedenen Mitarbeitern! MySQL erlaubte (vor 5.7) eine solche schlechte Verwendung der Gruppe, die zu fehlerhaften Ergebnissen führen könnte. Es wurde in 5.7 behoben und die Standardeinstellungen würden diese Abfrage ablehnen.
  • Die Bedingung:

    YEAR(created_at) = '2015' AND MONTH(created_at) = '12'

    Indizes können nicht verwendet werden. Es ist besser , mit entweder neu zu schreiben , BETWEENwenn die Spalte von ist DATETyp mit einer Inklusiv-exklusiven Bereich Bedingung, die problemlos mit jedem Datetime - Typ (funktioniert DATE, DATETIME, TIMESTAMP) aller Präzision:

    -- use only when the type is DATE only
    date BETWEEN '2015-12-01' AND LAST_DAY('2015-12-01')
    

    oder:

    -- use when the type is DATE, DATETIME or TIMESTAMP
    created_at >= '2015-12-01' AND created_at < '2016-01-01'     
    

Dies funktioniert nicht, da company_id in dv als OneTimeItems neu formatiert wurde, sodass Sie es nicht in der "ON-Klausel" verwenden können. Siehe Fehler: # 1054 - Unbekannte Spalte 'dv.company_id' in 'on-Klausel'
FMashiro

@FMashiro Sie haben oi.datein der Abfrage, aber der Pastebin hat keine datein dieser Tabelle.
Ypercubeᵀᴹ

Der Pastebin im Thread wurde aktualisiert und hier ist der Link noch einmal. Tut mir leid, dass
ich
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.