2016-07-11 14 views
2

Ich versuche, eine Liste von company_id 's zu erhalten, die keine Notizen auf Unternehmensebene haben. Die Firma kann jedoch Notizen auf Standortebene haben.MySQL Select Distinct mit linker Join?

company 
------------------------- 
company_id name deleted 
1   Foo 0 
2   Bar 0 
3   Baz 0 

location 
----------------------- 
location_id company_id 
6   1 
7   2 
8   3 

note 
----------------------------------------- 
note_id company_id location_id deleted 
10  2   6   0   // location-level note 
11  1   7   0   // location-level note 
12  null  8   0   // location-level note 
13  2   null   0   // company-level note 

Ich würde meine Ergebnistabelle dies sein will:

company_id name 
1   Foo 
3   Baz 

aktualisiert

Foo/company_id = 1 keine Unternehmensebene zur Kenntnis, weil die Note auch ein location_id hat, was es zu einer Notiz auf Standort-Ebene macht. Notizen auf Unternehmensebene sind Notizen, die nur auf eine Firma (und nicht auf einen Standort) verweisen.

Ende des Update

Ich habe versucht, so etwas wie dies zu tun, aber es gibt eine leere Menge, so dass ich bin mir nicht sicher, ob es funktioniert und es gibt keine Unternehmen ohne Unternehmensebene Notizen oder wenn ich etwas falsch mache.

SELECT DISTINCT 
c.company_id, 
c.name 
FROM company AS c 
LEFT JOIN note AS n 
ON c.company_id = n.company_id 
WHERE 
c.deleted = 0 AND 
n.deleted = 0 AND 
n.location_id IS NOT NULL AND 
n.location_id != 0 AND 
c.company_id = (SELECT MAX(company_id) FROM company) 

Überarbeitete akzeptierte Antwort von Mike

SELECT 
    company_id, 
    name 
FROM company 
WHERE 
    deleted = 0 AND 
    company_id NOT IN (
     SELECT DISTINCT 
      c.company_id 
     FROM company AS c 
     INNER JOIN note AS n 
     ON c.company_id = n.company_id 
     WHERE (
      n.deleted = 0 AND 
       (n.location_id IS NULL OR 
       n.location_id = 0) 
     ) 
    ); 
+1

'Deleted' Spalte fehlt in Beispieldaten, und diese Bedingungen' n.deleted = 0 und n.location_id IST NOT NULL UND n.location_id! = 0 'schaltet die 'Linke join' zu' Inner join ' –

+1

' c.company_id = (SELECT MAX (Firma_ID) FROM Firma) 'Dies wird sicherstellen, dass das Ergebnis hat nur eine' company_id' –

+0

@Prdp aktualisierte Frage zu enthalten gelöschte Spalten. Wie verhindere ich, dass die Linke zu einem Inner Join wird und gleichzeitig nur nach Firmennotizen gesucht wird? – GreeKatrina

Antwort

1

Der einfachste Weg, um darüber nachzudenken, die alle Unternehmen erste ist, finden die Unternehmensebene Notizen haben, die Sie mit

tun können
select distinct c.company_id 
    from company c 
inner join notes n 
    on c.company_id = n.company_id 
    where n.location_id is null; 

Dann entfernen Sie einfach diese Unternehmen aus der Firma wählen:

select company_id, 
     name 
    from company 
where company_id not in (select distinct c.company_id 
          from company c 
          inner join notes n 
           on c.company_id = n.company_id 
          where n.location_id is null); 

* Aktualisiert, um den inneren Join anstelle des durch Kommas getrennten Joins zu verwenden.

+1

Niemals vorschlagen 'Komma getrennt Join' wenn jemand explizite' Joins' verwendet. –

+0

Ich habe noch kein Komma getrennt Join gesehen, können Sie die Antwort bitte mit den Schlüsselwörtern aktualisieren, wie @Prdp vorgeschlagen? – GreeKatrina

+0

Ich habe nur ein paar weitere where-Klauseln zu Ihrer Abfrage hinzugefügt, und es funktioniert (aktualisierte Frage). Vielen Dank! – GreeKatrina

0
SELECT DISTINCT c.* 
    FROM company c 
    LEFT 
    JOIN note n 
    ON n.company_id = c.company_id 
    AND n.location_id IS NULL 
WHERE n.note_id IS NULL;