2016-07-19 19 views
0

Ich erstelle DB (MySQL 5.5, Ubuntu 14.04), wo ich Unternehmen nach Divisionen (die Firma gehört) und Stichwörtern suchen. Lassen Sie uns sagen, dass wir Tische haben -MySQL JOIN + WHERE gibt keine Ergebnisse

company (c_id,c_name) 
------------------------------- 
1 'A-Z hair' 
2 'My Coffee' 
3 'Boom Disco' 
4 'Go Cinema' 

keywords (c_fk , keyword) 
----------------- 
1 'haircut' 
1 'pruning' 
1 'coloring' 
2 'coffee' 
2 'tea' 
2 'free wifi' 

division(d_id , d_name) 
--------------- 
1 'shop' 
2 'service' 
3 'manufacturing' 
4 'engineering'  
5 'food' 
6 'entertainment' 

comp_div (c_fk , d_fk) 
----------------------- 
1 2 
2 5 
2 2 
4 6 

(.._ fk Spalten sind Fremdschlüssel-Verbindungen)
Ich brauche eine Auswahl mit mehreren optionalen Kriterien, die Unternehmen zurück, wo

(Unternehmen auf bestimmte Abteilung oder Sparte gehört doesn 't matter) UND
(etwas Firmen-Schlüsselwort ist' etwas 'ODER Schlüsselwörter sind egal)

Hier ist die sqlfiddle link. Leider gibt es einige Fehler und Mysql 5.5-Modus nicht funktioniert, so teste ich auf 5.6

beginne ich meine Suchabfrage mit der Erstellung Kompilieren

SELECT c_id,c_name,d_fk,keyword FROM company 
LEFT JOIN comp_div ON c_id=comp_div.c_fk 
LEFT JOIN keywords ON c_id=keywords.c_fk 

folgenden JOIN, die wie erwartet funktioniert und gibt alle Zeilen mit allen Unternehmen * divisions * keywords

Dann möchte ich Ergebnisse mit zusätzlichen WHERE verfeinern, also füge ich zB hinzu WHERE Schlüsselwort = 'etwas'. Natürlich gibt es ein Problem mit NULL-Vergleich, so dass WHERE fehlschlägt und die Abfrage keine Ergebnisse liefert. Ich beabsichtige, die Suchanfrage nach einem Fall zu erweitern, in dem Schlüsselwort und/oder Divisionsparameter vorhanden, aber auch nicht vorhanden sind. Also meine Idee ist, so etwas zu haben -

SELECT c_id,c_name,d_fk,keyword FROM company 
LEFT JOIN comp_div ON c_id=comp_div.c_fk 
LEFT JOIN keywords ON c_id=keywords.c_fk 
WHERE (''=keyword OR keyword LIKE somethin%) AND 
(comp_div.d_fk=<division_fk> OR comp_div.d_fk = 0) 

Ich versuche verzweifelt alle Methoden, z.
1. ON Bewegungszustand ..

SELECT c_id,c_name,d_fk,keyword FROM company  
LEFT JOIN comp_div ON c_id=comp_div.c_fk  
LEFT JOIN keywords ON (c_id=keywords.c_fk) AND (keyword='something') 

die seltsame Art und Weise funktioniert, wie es führt alle mit null Schlüsselwort gibt

2.applying WHERE auf abgeleitete Tabelle ohne WHERE + IFNULL/COALESCE

SELECT c_id,c_name,d_fk,keyword FROM( 
SELECT c_id,c_name,d_fk,keyword FROM company  
LEFT JOIN comp_div ON c_id=comp_div.c_fk 
LEFT JOIN keywords ON c_id=keywords.c_fk) dt 
WHERE COALESCE(dt.keyword,'')='something' 

das ist wahrscheinlich dumm und gibt keine Ergebnisse zurück.

Bitte beachten Sie die Best Practices für diese Aufgabe. Vielen Dank.

+0

Könnten Sie bitte und ** sql Geige ** mit einigen Beispieldaten teilen?Erwähnen Sie auch Ihre erwartete Ausgabe in Tabellenform. – 1000111

+0

Ich fügte Beispieltabellen und SQLFiddle meinem ursprünglichen Post hinzu – Anderquo

Antwort

0

Nach Stunden der Studien und Studie nächste Lösung gefunden wird - meine Absicht war ursprünglich, 2 Auswahlen, eine für jedes Kriterium (Division, Schlüsselwort) durchzuführen und dann schneiden von Tabellen. Wie INTERSECT nicht in MySQL unterstützt, kann es wie hier von IN-Operator und Unterabfrage simuliert werden -

SELECT c_id,c_name FROM company 
LEFT JOIN keywords K ON c_id=K.c_fk AND K.keyword LIKE @keyword 
WHERE (K.c_fk IS NOT NULL OR @keyword='') AND 
c_id IN (
SELECT c_id FROM company 
LEFT JOIN comp_div D ON c_id=D.c_fk AND D.d_fk = @division 
WHERE D.c_fk IS NOT NULL OR @division=-1) 
GROUP BY c_id 

Trick besteht darin, herauszufinden, was mit LEFT geschieht JOIN Ergebnis, wenn gültige Kriterien angewandt wird und wenn Kriterien weggelassen wird (@ Schlüsselwort = ''). Im ersten Fall (@keyword <> '') müssen wir alle Zeilen entfernen, die NULL auf der rechten Seite haben (diejenigen, die nicht übereinstimmen), und es wird durch die IS NOT NULL-Klausel erledigt.
In letzterem Fall wollen wir alle Zeilen, egal welche Schlüsselwörter sind. Das wird durch WHERE TRUE gewährleistet. Second SELECT ist identisch in der Struktur, es verwendet nur Divisions-ID als Kriterium (-1 für egal) Mit mehr IN-Konstruktionen kann eine notwendige Anzahl von Kriterien angewendet werden.