मेरे पास दो टेबल हैं:

टेबल उपयोगकर्ता:

create table user (
   id bigserial not null primary key,
   username varchar(256),
   active boolean not null default true
);

और टेबल पता:

create table address (
   id bigserial not null primary key,
   user_id integer not null,
   country varchar(256),
   city varchar(256),
   street varchar(256)
);

और उदाहरण के रूप में कुछ डेटा:

insert into user(id, username, active) values (1, 'john', true);
insert into user(id, username, active) values (2, 'alex', true);
insert into user(id, username, active) values (3, 'alice', true);
insert into user(id, username, active) values (4, 'tom', true);
insert into user(id, username, active) values (5, 'dave', true);

insert into address(id, user_id, country, city, street) values (1, 1, 'Germany', 'Berlin', '');
insert into address(id, user_id, country, city, street) values (2, 2, 'Germany', 'Berlin', '');
insert into address(id, user_id, country, city, street) values (3, 2, 'Great Britain', 'London', '');
insert into address(id, user_id, country, city, street) values (4, 3, 'France', 'Paris', '');
insert into address(id, user_id, country, city, street) values (5, 4, 'USA', 'New York', '');
insert into address(id, user_id, country, city, street) values (6, 5, 'South Korea', 'Seoul', '');

प्रत्येक उपयोगकर्ता के कई पते हो सकते हैं। मुझे उन सभी उपयोगकर्ताओं को प्राप्त करने की आवश्यकता है जिनके पास विशिष्ट देश के पते के सेट में नहीं है, उदाहरण के लिए 'जर्मनी'।

मैंने क्या प्रयास किया:

select u.* from user u
left join address a on u.id=a.user_id where a.country is not like '%Germany%'

लेकिन यह उन उपयोगकर्ताओं को लौटाता है, जिनके पास विशिष्ट देश का पता है, लेकिन कुछ अन्य पता भी है, कौन सा देश विशिष्ट से अलग है, उदाहरण के लिए ऊपर उपयोग किए गए डेटा के साथ एलेक्स है, जिसके दो पते जर्मनी और ग्रेट ब्रिटेन हैं:

id  username  active
--------------------
2   alex      True
3   alice     True
4   tom       True
5   dave      True

कोई सुझाव मैं ऐसी क्वेरी कैसे कर सकता हूं?

0
Dypsi 23 सितंबर 2020, 18:16

2 जवाब

सबसे बढ़िया उत्तर

आपका कोड जांचता है कि प्रत्येक उपयोगकर्ता का जर्मनी के बाहर कम से कम एक पता है या नहीं, जबकि आप यह सुनिश्चित करना चाहते हैं कि उनके पास कोई पता नहीं है।

मेरा सुझाव है not exists:

select c.*
from client c
where not exists (
    select 1
    from address a 
    where a.user_id = c.id and a.country = 'Germany'
)

यह क्वेरी address(user_id, country) पर एक इंडेक्स का लाभ उठाएगी।

ध्यान दें कि यह स्पष्ट नहीं है कि आपकी तालिका को user कहा जाता है या client... मैंने बाद वाले का उपयोग किया है।

ध्यान दें कि यह उन ग्राहकों को भी लौटाता है जिनके पास कोई पता नहीं है। यदि वह नहीं है जो आप चाहते हैं, तो एक विकल्प एकत्रीकरण का उपयोग करता है:

select c.*
from client c
inner join address on a.user_id = c.id
group by c.id
having not bool_or(a.country = 'Germany')
2
GMB 23 सितंबर 2020, 18:25

यह क्वेरी है:

select user_id from address where country = 'Germany'

जो उन सभी उपयोगकर्ताओं को लौटाता है जिन्हें आप फ़िल्टर करना चाहते हैं।
NOT IN के साथ इसका प्रयोग करें:

select u.* 
from user u
where id not in (select user_id from address where country = 'Germany')

डेमो देखें।
परिणाम:

> id | username | active
> -: | :------- | :-----
>  3 | alice    | t     
>  4 | tom      | t     
>  5 | dave     | t     
0
forpas 23 सितंबर 2020, 18:28