2016-11-29 4 views
2

Zum Beispiel, wenn ich Bälle und Boxen habe, können Bälle in vielen Boxen sein, und Boxen können gesperrt werden, wie kann ich die Bälle auswählen, die nicht in einer verschlossenen Box sind?Ausgeschlossene Datensätze für Spaltenwert ausschließen?

balls 
    id name 
    == ==== 
    1 in neither 
    2 in unlocked 
    3 in locked 
    4 in both 

boxes 
    id locked 
    == ====== 
    1 0 
    2 1 

boxings 
    ball_id box_id 
    ======= ====== 
    2  1 
    3  2 
    4  1 
    4  2 

Ich habe mit dieser mit links schließt sich kommen, aber es ist das „in beiden“ Ball Rückkehr, die ich ausschließen wollen.

SELECT balls.* 
FROM balls 
LEFT OUTER JOIN boxings ON boxings.ball_id = balls.id 
LEFT OUTER JOIN boxes ON boxes.id = boxings.box_id 
WHERE (boxings.box_id IS NULL or boxes.locked = 0) 
    AND boxes.id NOT IN (
    SELECT id FROM boxes WHERE locked = 1 
    ) 

Wunschergebnisse:

id name 
== ==== 
1 in neither 
2 in unlocked 

SQL Fiddle: http://sqlfiddle.com/#!9/c26ab/4

Antwort

2

Ich nehme an, Sie bedeuten: wählen Kugeln, die nie in einer verschlossenen Box sind.

Wenn ja, eine not exists Abfrage in den Sinn kommt:

select b.* 
from balls b 
where not exists (select 1 
        from boxings bxb join 
         boxes bo 
         on bxb.box_id = bo.id 
        where bxb.ball_id = b.id and bo.locked = 1 
       ); 
+0

, dass es, Dank! – jemminger

0

Die straightforwad Weg, dies zu tun, ist wahrscheinlich mit NOT EXISTS:

select id, name 
from balls 
where not exists (
    select NULL 
    from boxings 
    inner join boxes on boxes.id = boxings.box_id 
    where boxes.locked = 1 
    and boxings.ball_id = balls.id 
) 
0

Ich finde es interessant, dass beide Antworten bereits beide geschrieben nehmen Sie den gleichen leicht ungeraden Ansatz, einige der Beitrittskriterien in die WHERE Klausel:

inner join boxes on boxes.id = boxings.box_id 
where boxes.locked = 1 

Was am seltsamsten ist, dass ich sicher the same people advise elsewhere to not put join conditions in WHERE clauses bin.

Wie auch immer, hier ist eine andere Variante des Anti-Join-Ansatz:

SELECT * 
    FROM balls 
WHERE id NOT IN (SELECT ball_id 
        FROM boxings 
          NATURAL JOIN 
          (SELECT id AS box_id FROM boxes WHERE locked = 1) 
          NATURAL JOIN 
          (SELECT id AS ball_id FROM boxings)); 
Verwandte Themen