2016-06-28 11 views
0

Arbeiten mit Android SMS-Benachrichtigung mit SQLite.SQL-Abfragen zwischen drei Tabellen

erhielt drei Tabellen mit dem Namen

people: `id`, `people_name` 
info: `id`,`info_name` 
people_info: `auto-increment id`, 
     `people_id` <- foreign key (people.id) 
     `info_id` <- foreign key (info.id) 

Wenn die Leute der Info benachrichtigt werden, die people_info die beiden IDs erstellt. Wie man die WHERE-Klausel macht, um zu überprüfen, ob die Leute informiert sind; wie man Personen ausfindig macht, die vollständig benachrichtigt sind und die Redundanz von Benachrichtigungen verhindern.

+0

können Sie Probe hinzufügen Datensatz wird es helfen, zu untersummieren –

+0

Überprüfen Sie die Beispieltabelle Bild? mit wenigen Beispieldaten – Aelaf

+0

können Sie es an Frage –

Antwort

1

Um Zeilen aus people, wo nicht eine Reihe dort zu diesen people und einer bestimmten Zeile in info verwendet ist, können Sie ein Anti-Join Muster verwenden.

Zum Beispiel:

SELECT p.id   AS `person_id` 
    , p.people_name AS `person_name` 
    FROM people p 
    LEFT 
    JOIN people_info i 
    ON i.people_id = p.id 
    AND i.info_id = ? 
WHERE i.people_id IS NULL 
ORDER BY p.id 

Dies ist nicht die einzige Abfrage Muster, das dieses Ergebnis zurückgibt. Es gibt ein paar andere, zum Beispiel eine nicht mit EXISTS und korrelierte Unterabfrage:

SELECT p.id   AS `person_id` 
    , p.people_name AS `person_name` 
    FROM people p 
WHERE NOT EXISTS (SELECT 1 
         FROM people_info i 
        WHERE i.people_id = p.id 
         AND i.info_id = ? 
       ) 
ORDER BY p.id 

Wenn Sie alle (people,info) Tupel zurückgeben möchten, die nicht verwandt sind, sondern als ein nur einem einzigen info, das kann auch erreicht werden. Die angegebene Spezifikation ist nicht eindeutig, welche Werte bereitgestellt werden, und ein Beispiel für die erwartete Ausgabe. Die obige Antwort bezieht sich nur auf eine von mehreren möglichen Interpretationen.

Wenn wir alle drei Tabellen einbeziehen wollen ... alle Infos für alle Menschen zu bekommen, die noch nicht gemeldet wurden, können wir eine verwenden anti-join Muster:

SELECT p.id   AS `person_id` 
    , p.people_name AS `person_name` 
    , i.id   AS `info_id` 
    , i.info_name AS `info_name` 
    FROM people p 
CROSS 
    JOIN info i 
    LEFT 
    JOIN people_info n 
    ON n.people_id = p.id 
    AND n.info_id = i.id 
WHERE n.people_id IS NULL 
ORDER BY p.id, i.id 
+0

gut Himmel! Ich werde sicher über deine sql Weisheit nachdenken. Herzlichen Dank, bevor ich deinen Code-Rat teste ;-) – Aelaf

+0

VIELEN DANK !!! nur eine letzte Frage, die ich weiter in verschiedene Informationen mit nicht wiederholenden Informationen ('i.id') abrufen möchte, versuchte' DISTINCT'. Schlüsselwort, funktioniert nicht. – Aelaf

+0

Das Schlüsselwort 'DISTINCT' (nach dem Schlüsselwort' SELECT') gilt für * alle * Ausdrücke in der Auswahlliste. Wenn Sie nur Zeilen von 'info' möchten, bei denen mindestens eine' people' nicht gemeldet wurde, kann diese Abfrage anders geschrieben werden. Um jedoch die obigen Beispielabfragen zu ändern, können Sie alle Verweise auf 'p.-Spalten aus der SELECT-Liste entfernen (dh nur Spalten mit i zurückgeben) und dann das Schlüsselwort DISTINCT hinzufügen. Aber es gibt bessere Möglichkeiten, das gewünschte Ergebnis zu erzielen. Ohne Beispiel für die erwartete Ergebnismenge ist die Spezifikation mehrdeutig und wir erraten nur, was Sie erreichen möchten. – spencer7593