2016-12-02 4 views
1

Hat viele Suchvorgänge ausgeführt und konnte alle JOIN-Abfragen außer dieser schreiben. Ich habe 3 Tabellen, die wie folgt aussehen:MySQL - gibt einen einzelnen Datensatz zurück, indem mehrere Tabellen mit mehreren WHERE/OR-Klauseln verbunden werden

TABLE - accounts 
account_id | account_email 
1   | [email protected] 
2   | [email protected] 

TABLE - products 
product_id | product_name 
1   | name1 
2   | name2 

TABLE - licenses 
license_id | account_id | product_id | license_code 
1   | 1   | 1   | 
2   | 1   | 2   | 
3   | 0   | 1   | abc123 

Ich weiß account_email, product_id und license_code (dieses kann leer sein) Variablen und müssen überprüfen, ob Client-Lizenz für ausgewählte Produkt (Suche nach account_email oder license_code) hat .

Das Problem ist, dass account_id manchmal 0 sein kann (mit anderen Worten, Client hat Lizenz, aber Client-Profil wird nicht in der Konten-Tabelle gespeichert).

Der Versuch, diese zu verwenden, aber es gibt falsch (dupliziert) Ergebnisse:

SELECT * FROM licenses 
INNER JOIN products ON licenses.product_id=products.product_id AND products.product_id='X' 
INNER JOIN accounts ON licenses.account_id=accounts.account_id AND accounts.account_email='XYZ' OR licenses.license_code='ZZZ' 

Die Frage: Wie umschreiben ich Abfrage, so kann ich eine Aufzeichnung von account_email oder license_code Feld finden? Einfach gesagt, wenn account_id nicht 0 ist (Profil existiert), sollte ich Daten aus 3 Tabellen sehen (Konten, Produkte, Lizenzen). Wenn account_id 0 ist, sollte ich Daten aus 2 Tabellen sehen (Werte aus der Account-Tabelle sollten als leer/null angezeigt werden).

Unnötig zu sagen, account_email und license_code Felder sind einzigartig.

Antwort

0

Nach ein paar mehr Code-Modifikation und Tests, hier ist der Code, der perfekt funktioniert. Es ist ein modifizierter Code von Gordon Linoff (der ursprüngliche Code funktionierte nicht, wenn nur der Lizenzcode bekannt war und die E-Mail-Adresse nicht bekannt war). So gehen die meisten Credits an Gordon Linoff für seine Bemühungen.

SELECT * 
FROM licenses l JOIN 
    products p 
    ON l.product_id = p.product_id LEFT JOIN 
    accounts a 
    ON l.account_id = a.account_id 
WHERE p.product_id = 'X' AND 
     (a.account_email='XYZ' OR l.license_code = 'ZZZ') 
0

Sie müssen nur die Klammern anpassen. Allerdings würde ich eine separate WHERE-Klausel verwenden:

SELECT * 
FROM licenses l INNER JOIN 
    products p 
    ON l.product_id = p.product_id INNER JOIN 
    accounts a 
    ON l.account_id = a.account_id 
WHERE p.product_id = 'X' AND 
     (a.account_email='XYZ' OR l.license_code = 'ZZZ') 

Sie die Filter in den ON Klauseln halten können - es gibt nichts falsch mit dem. Ich bevorzuge es, Join-Bedingungen von Filterbedingungen zu trennen. Der wichtige Teil sind die Klammern, so dass die ON Klausel nicht interpretiert als:

ON (l.account_id = a.account_id AND a.account_email = 'XYZ') OR 
    licenses.license_code = 'ZZZ' 

Dies ist die Interpretation ohne parens.

+0

müssen 'UND' vor dem 2. Join entfernen :) –

+0

Danke für den Vorschlag. Es hat mehrere SQL-Fehler angezeigt, also habe ich es ein wenig modifiziert, indem ich 'AND' vor dem 2. Join entfernt habe und 'AND' vor dem letzten 'WHERE' entfernt habe. Hoffe, es ist immer noch in Ordnung? –

+0

Leider funktioniert der Code nicht. Es funktioniert gut, wenn Account_email in der Datenbank vorhanden ist, aber wenn Account_email nicht in der Datenbank vorhanden ist (also Datensatz muss nach license_code gefunden werden), werden 0 Ergebnisse angezeigt. –

Verwandte Themen