उन पंक्तियों का चयन करें जो अन्य तालिका में मौजूद नहीं हैं


172

मुझे दो पोस्टग्रेजल टेबल मिले हैं:

table name     column names
-----------    ------------------------
login_log      ip | etc.
ip_location    ip | location | hostname | etc.

मैं प्रत्येक आईपी पते को प्राप्त करना चाहता हूं login_logजिसमें से एक पंक्ति नहीं है ip_location
मैंने इस क्वेरी की कोशिश की, लेकिन यह एक सिंटैक्स त्रुटि फेंकता है।

SELECT login_log.ip 
FROM login_log 
WHERE NOT EXIST (SELECT ip_location.ip
                 FROM ip_location
                 WHERE login_log.ip = ip_location.ip)
ERROR: syntax error at or near "SELECT"
LINE 3: WHERE NOT EXIST (SELECT ip_location.ip`

मैं यह भी सोच रहा हूं कि क्या यह क्वेरी (इसे काम करने के लिए समायोजन के साथ) इस उद्देश्य के लिए सबसे अच्छा प्रदर्शन करने वाला प्रश्न है।

जवाबों:


386

इस कार्य के लिए मूल रूप से 4 तकनीकें हैं, उनमें से सभी मानक एसक्यूएल हैं।

NOT EXISTS

Postgres में अक्सर सबसे तेज।

SELECT ip 
FROM   login_log l 
WHERE  NOT EXISTS (
   SELECT  -- SELECT list mostly irrelevant; can just be empty in Postgres
   FROM   ip_location
   WHERE  ip = l.ip
   );

इस पर भी विचार करें:

LEFT JOIN / IS NULL

कभी-कभी यह सबसे तेज होता है। अक्सर सबसे छोटा। अक्सर उसी क्वेरी प्लान के रूप में परिणाम होता है NOT EXISTS

SELECT l.ip 
FROM   login_log l 
LEFT   JOIN ip_location i USING (ip)  -- short for: ON i.ip = l.ip
WHERE  i.ip IS NULL;

EXCEPT

कम। अधिक जटिल प्रश्नों में आसानी से एकीकृत नहीं है।

SELECT ip 
FROM   login_log

EXCEPT ALL  -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM   ip_location;

ध्यान दें कि ( प्रति प्रलेखन ):

जब तक EXCEPT ALLउपयोग नहीं किया जाता तब तक डुप्लिकेट को समाप्त कर दिया जाता है।

आमतौर पर, आप ALLकीवर्ड चाहते हैं । यदि आप परवाह नहीं करते हैं, तब भी इसका उपयोग करें क्योंकि यह क्वेरी को तेज़ बनाता है ।

NOT IN

केवल NULLमूल्यों के बिना अच्छा है या यदि आप NULLठीक से संभालना जानते हैं । मैं इस उद्देश्य के लिए इसका इस्तेमाल नहीं करूंगा । इसके अलावा, प्रदर्शन बड़ी तालिकाओं के साथ बिगड़ सकता है।

SELECT ip 
FROM   login_log
WHERE  ip NOT IN (
   SELECT DISTINCT ip  -- DISTINCT is optional
   FROM   ip_location
   );

NOT INNULLदोनों तरफ के मूल्यों के लिए एक "जाल" किया जाता है :

MySQL पर लक्षित dba.SE पर समान प्रश्न:


2
दोनों तालिकाओं में डेटा वॉल्यूम उच्च होने पर विचार करते हुए कौन सा एसक्यूएल तेजी से चलेगा। (अरबों में ग्रहण करना)
तेजा

मेरे लिए सब कुछ सबसे तेज़ था
Dan Parker

सावधान रहें LEFT JOIN- यदि लुकअप तालिका में कई मिलान पंक्तियाँ हैं, तो यह प्रत्येक मिलान पंक्ति के लिए आपकी मुख्य क्वेरी में एक डुप्लिकेट प्रविष्टि बनाएगी, जो कि नहीं चाहिए।
मथायस फ्रायप

@ मैथिअसफ्रिप: इसके अलावा ऐसा कभी भी नहीं हो सकता है WHERE i.ip IS NULL, जिसका अर्थ है कोई मैच नहीं
एरविन ब्रैंडस्टैटर

@ erwin-brandstetter: अच्छी बात है। मैंने कई सकारात्मक मैचों की संभावना के बारे में सोचते हुए खुद को टाल दिया, लेकिन निश्चित रूप से उन सभी को बाहर रखा जाएगा।
मथायस फ्रायप

2

ए) कमांड एक्जिट नहीं है, आप 'एस' को याद कर रहे हैं।

बी) इसके बजाय में उपयोग नहीं

SELECT ip 
  FROM login_log 
  WHERE ip NOT IN (
    SELECT ip
    FROM ip_location
  )
;

4
बड़े डेटासेट पर नहीं एक भयानक विचार है। बहुत, बहुत धीमा। यह खराब है और इससे बचना चाहिए।
ग्रेजेगॉर ग्रेबेक

0

SELECT * FROM testcases1 t WHERE NOT EXISTS ( SELECT 1
FROM executions1 i WHERE t.tc_id = i.tc_id and t.pro_id=i.pro_id and pro_id=7 and version_id=5 ) and pro_id=7 ;

यहाँ testcases1 तालिका में सभी डेटा शामिल हैं और निष्पादित 1 तालिका में testcases1 तालिका के बीच कुछ डेटा शामिल हैं। मैं केवल उन डेटा को पुनः प्राप्त कर रहा हूं जो एक्सन 1 टेबल में मौजूद नहीं हैं। (और यहां तक ​​कि मैं अंदर कुछ शर्तें दे रहा हूं जो आप भी दे सकते हैं।) ऐसी स्थिति निर्दिष्ट करें जो डेटा पुनर्प्राप्त करने में नहीं होनी चाहिए और ब्रैकेट के अंदर होनी चाहिए।


0

यह भी कोशिश की जा सकती है ...

SELECT l.ip, tbl2.ip as ip2, tbl2.hostname
FROM   login_log l 
LEFT   JOIN (SELECT ip_location.ip, ip_location.hostname
             FROM ip_location
             WHERE ip_location.ip is null)tbl2

2
WHERE ip_location.ip is null- WHEREहालत कभी सच कैसे हो सकती है? इसके अलावा, उप-क्वेरी एक सहसंबद्ध नहीं है।
इस्तियाक अहमद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.