2014-11-21 20 views
8

Trong PostgreSQL 9 trên CentOS 6 có 60000 bản ghi trong pref_users bảng:Tham gia bên ngoài bên trái - làm thế nào để trả về một boolean cho sự tồn tại trong bảng thứ hai?

# \d pref_users 
        Table "public.pref_users" 
    Column |   Type    |  Modifiers  
------------+-----------------------------+-------------------- 
id   | character varying(32)  | not null 
first_name | character varying(64)  | not null 
last_name | character varying(64)  | 
login  | timestamp without time zone | default now() 
last_ip | inet      | 
(... more columns skipped...) 

Và bảng khác nắm giữ khoảng 500 id của người sử dụng mà không được phép chơi nữa:

# \d pref_ban2 
       Table "public.pref_ban2" 
    Column |   Type    | Modifiers 
------------+-----------------------------+--------------- 
id   | character varying(32)  | not null 
first_name | character varying(64)  | 
last_name | character varying(64)  | 
city  | character varying(64)  | 
last_ip | inet      | 
reason  | character varying(128)  | 
created | timestamp without time zone | default now() 
Indexes: 
    "pref_ban2_pkey" PRIMARY KEY, btree (id) 

Trong một PHP kịch bản Tôi đang cố gắng hiển thị tất cả 60000 người dùng từ pref_users trong một jQuery-dataTable. Và tôi muốn đánh dấu những người dùng bị cấm (những người sử dụng được tìm thấy trong pref_ban2).

Điều này có nghĩa là tôi cần một cột có tên ban cho mỗi bản ghi trong truy vấn của tôi đang giữ true hoặc false.

Vì vậy, tôi đang cố gắng một trái bên ngoài tham gia truy vấn:

# select       
     b.id, -- how to make this column a boolean? 
     u.id, 
     u.first_name, 
     u.last_name, 
     u.city, 
     u.last_ip, 
     to_char(u.login, 'DD.MM.YYYY') as day 
from pref_users u left outer join pref_ban2 b on u.id=b.id 
limit 10; 
id | id | first_name | last_name | city  |  last_ip  | day  
----+----------+-------------+-----------+-------------+-----------------+------------ 
    | DE1  | Alex  |   | Bochum  | 2.206.0.224  | 21.11.2014 
    | DE100032 | Княжна Мэри |   | London  | 151.50.61.131 | 01.02.2014 
    | DE10011 | Aлександр Ш |   | Симферополь | 37.57.108.13 | 01.01.2014 
    | DE10016 | Semen10  |   | usa   | 69.123.171.15 | 25.06.2014 
    | DE10018 | Горловка |   | Горловка | 178.216.97.214 | 25.09.2011 
    | DE10019 | -Дмитрий- |   | пермь  | 5.140.81.95  | 21.11.2014 
    | DE10047 | Василий  |   | Cумы  | 95.132.42.185 | 25.07.2014 
    | DE10054 | Maedhros |   | Чикаго  | 207.246.176.110 | 26.06.2014 
    | DE10062 | ssergw  |   | москва  | 46.188.125.206 | 12.09.2014 
    | DE10086 | Вадим  |   | Тула  | 109.111.26.176 | 26.02.2012 
(10 rows) 

Như bạn có thể thấy b.id cột trên là rỗng - bởi vì những 10 người dùng không bị cấm.

Cách lấy giá trị false trong cột đó thay vì chuỗi?

Và tôi không tuân theo một số biểu thức coalesce hoặc case, nhưng tôi đang tìm cách "thích hợp" để thực hiện truy vấn đó.

Trả lời

8

Tuyên bố CASE hoặc COALESCE với tham gia bên ngoài LÀ cách thích hợp để thực hiện việc này.

select 
    CASE 
    WHEN b.id IS NULL THEN true 
    ELSE false 
    END AS banned,       
    u.id, 
    u.first_name, 
    u.last_name, 
    u.city, 
    u.last_ip, 
    to_char(u.login, 'DD.MM.YYYY') as day 
from pref_users u 
left outer join pref_ban2 b 
    on u.id=b.id 
limit 10; 
+0

Cảm ơn câu trả lời của bạn, nhưng tôi có nên sử dụng 'exist' ở đây một cách hiệu quả hơn không? –

+0

Vì vậy, 'EXISTS' hoạt động như một bộ lọc. Nếu bạn sử dụng 'EXISTS', bạn sẽ không nhận được bản ghi nếu nó được lọc ra. Nếu bạn muốn hiển thị một giá trị 'boolean', bạn sẽ tốt hơn với' CASE'. –

+0

Đến thời điểm đó, bạn có thể sử dụng 'EXISTS' thay cho' OUTER JOIN' nhưng điều đó sẽ không thay đổi logic boolean. –

3

"IS NULL" và "IS NOT NULL" trả về boolean, vì vậy việc này sẽ dễ dàng.

Tôi nghĩ rằng đây là tất cả những gì bạn cần?

SELECT       
     b.id IS NOT NULL as is_banned, -- The value of "is_banned" will be a boolean 

Không chắc chắn bạn có cần "KHÔNG" hay không, nhưng bạn sẽ nhận được bool một trong hai cách.

+0

Giải pháp tốt hơn so với câu trả lời được chấp nhận! – mes

Các vấn đề liên quan