Frage

Betrachten Sie die folgende Tabelle:

mysql> select * from phone_numbers;
+-------------+------+-----------+
| number      | type | person_id |
+-------------+------+-----------+
| 17182225465 | home |         1 |
| 19172225465 | cell |         1 |
| 12129876543 | home |         2 |
| 13049876543 | cell |         2 |
| 15064223454 | home |         3 |
| 15064223454 | cell |         3 |
| 18724356798 | home |         4 |
| 19174335465 | cell |         5 |
+-------------+------+-----------+

Ich versuche, die Leute zu finden, die Home-Telefone haben aber keine Zellen.

Diese Abfrage funktioniert:

mysql> select h.*
    -> from phone_numbers h
    -> left join phone_numbers c
    -> on h.person_id = c.person_id
    -> and c.type = 'cell'
    -> where h.type = 'home'
    -> and c.number is null;
+-------------+------+-----------+
| number      | type | person_id |
+-------------+------+-----------+
| 18724356798 | home |         4 |
+-------------+------+-----------+

, aber dies nicht:

mysql> select h.*
    -> from phone_numbers h
    -> left join phone_numbers c
    -> on h.person_id = c.person_id
    -> and h.type = 'home'
    -> and c.type = 'cell'
    -> where c.number is null;
+-------------+------+-----------+
| number      | type | person_id |
+-------------+------+-----------+
| 19172225465 | cell |         1 |
| 13049876543 | cell |         2 |
| 15064223454 | cell |         3 |
| 18724356798 | home |         4 |
| 19174335465 | cell |         5 |
+-------------+------+-----------+

Der einzige Unterschied zwischen den beiden ist die Lage des h.type = 'home' Zustand -. In der ersten ist es in der where Klausel und in der zweiten ist es ein Teil der on Klausel

Warum nicht die zweite Abfrage das gleiche Ergebnis wie die erste Rückkehr?

War es hilfreich?

Lösung

In der zweiten SQL, die Bedingung h.type = ‚Heimat‘ ist ein Teil der äußeren Bedingungen beizutreten, und ist kein Filter auf die Ergebnisse. Für alle Datensätze, in denen h.type = ‚Zelle‘, die Bedingung h.type = ‚Heimat‘ FALSCH ist und so keine „passende“ c Zeile gefunden wird - so C Anzahl ist null, was Ihre einzige Filterung (WO) Zustand .

In Pseudo-Code Ihrer 2. SQL funktioniert wie folgt:

for each row in phone_numbers h /* Note this is ALL home AND cell phones */
   select c.number from phone_numbers c
   where h.person_id = c.person_id
   and h.type = 'home'
   and c.type = 'cell';
   if c.number is null (i.e. no row found)
     display h.*
   end if
end loop;

Andere Tipps

Wenn links tun verbindet ich die Dinge auf diese Weise nähern. Im beitreten müssen Sie anny Felder, die eigentlich verbinden die beiden Tabellen zusammen und jede Filterbedingung von der rechten Seite (zweite Tabelle in der Join) die Verbindung angeben (mit einer Ausnahme, ich werde in Kürze erhalten). Filterbedingungen von der linken Seite der join (1. Tabelle) sollen in der where-Klausel sein oder sie werden falsch beeinflussen die Verbindung, wie Sie sahen (und wie Tony so erklärten schön). Die einzige Zeit, die rechte Seite der Verknüpfung sollte in dem seine where-Klausel ist, wenn Sie für NULL-Werte in dieser Tabelle (das heißt, die Datensätze, die in der ersten Tabelle sind aber nicht die zweite) suchen.

SEL * 
FROM phone_numbers T1
WHERE typeS='home' AND person_id NOT IN
(SELECT person_id FROM phone_numbers  T2 WHERE T1.person_id=T2.person_id AND  typeS='cell')

Sie können diese Abfrage versuchen, ich hoffe, es wird für Sie arbeiten.

select * from phone_numbers
where person_id not in (select person_id from phone_numbers where type='cell')

Ich weiß nicht, ob dies die Dinge repariert oder nicht, aber ...

Die Aussagen, die mit „und“ sollte Teil der WHERE-Klausel, die nicht Teil der ON-Klausel sein. Die ON-Klausel sollte nur haben Aussagen, welche die Spalten werden verwendet, um die Tabellen zu verknüpfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top