سؤال

خذ بعين الاعتبار الجدول التالي:

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 |
+-------------+------+-----------+

أحاول العثور على هؤلاء الأشخاص الذين لديهم هواتف منزلية ولكن ليس لديهم هواتف خلوية.

يعمل هذا الاستعلام:

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 |
+-------------+------+-----------+

ولكن هذا لا:

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 |
+-------------+------+-----------+

والفرق الوحيد بين الاثنين هو موقع h.type = 'home' الحالة - في الأول كان في where جملة وفي الثانية جزء من on بند.

لماذا لا يُرجع الاستعلام الثاني نفس نتيجة الاستعلام الأول؟

هل كانت مفيدة؟

المحلول

في SQL الثاني، و= حالة h.type 'الوطن' هو جزء من صلة خارجية الظروف، وليس تصفية على النتائج. لكافة السجلات حيث h.type = 'خلية'، وh.type حالة = 'الوطن' هي FALSE وهكذا لم يتم العثور على "مطابقة" الصف ج - حتى c.number هو باطل، وهو الخاص الترشيح فقط (WHERE) حالة .

في شبه كود SQL 2ND الخاص بك يعمل مثل هذا:

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;

نصائح أخرى

عند القيام اليسار ينضم I يتعاملوا مع الامور بهذه الطريقة. في الانضمام تحتاج إلى تحديد المجالات العاني التي تصل في الواقع الجدولين معا وأي حالة التصفية من الجانب الأيمن (الجدول 2ND في الانضمام) للانضمام (مع استثناء واحد، سأحضر لفترة وجيزة). وينبغي أن تكون شروط التصفية من الجانب الأيسر من الانضمام (الجدول 1ST) في جملة WHERE أو أنها سوف تؤثر على خطأ الصلة كما رأيتم (وتوني ذلك أوضح لطيف). يجب أن تكون هذه هي المرة الوحيدة الجانب الأيمن من الانضمام في حيث الشرط إذا كنت تبحث عن القيم الخالية في هذا الجدول (أي السجلات التي هي في الجدول الأول ولكن ليس الثانية).

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')

ويمكنك أن تجرب هذا الاستعلام، وآمل انها سوف تعمل من أجلك.

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

لا أعرف إذا كان هذا سيصلح الأمور أم لا، لكن...

يجب أن تكون العبارات التي تبدأ بـ "و" جزءًا من جملة WHERE، وليست جزءًا من جملة ON.يجب أن تكون جملة ON فقط تحتوي على عبارات تتضمن الأعمدة المستخدمة لربط الجداول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top