Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Left outer join - how to return a boolean for existence in the second table?

In PostgreSQL 9 on CentOS 6 there are 60000 records in pref_users table:

# \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...)

And another table holds around 500 ids of users which are not allowed to play anymore:

# \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)

In a PHP script I am trying to display all 60000 users from pref_users in a jQuery-dataTable. And I would like to mark the banned users (the users found in pref_ban2).

Which means I need a column named ban for each record in my query holding true or false.

So I am trying a left outer join query:

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

As you can see the b.id column above is empty - because these 10 users aren't banned.

How to get a false value in that column instead of a String?

And I am not after some coalesceor case expression, but am looking for "the proper" way to do such a query.

like image 429
Alexander Farber Avatar asked Nov 21 '14 17:11

Alexander Farber


People also ask

What does left outer join Return?

Left Outer Join returns all the rows from the table on the left and columns of the table on the right is null padded. Left Outer Join retrieves all the rows from both the tables that satisfy the join condition along with the unmatched rows of the left table.

How do I join two tables with left join in SQL?

Syntax For Left Join:SELECT column names FROM table1 LEFT JOIN table2 ON table1. matching_column = table2. matching_column; Note: For example, if you have a left table with 10 rows, you are guaranteed to have at least 10 rows after applying join operation on two tables.

Does LEFT join return all rows?

The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in the right table; the join will still return a row in the result, but with NULL in each column from the right table.

When outer joins are used on two tables?

In SQL, a join is used to compare and combine — literally join — and return specific rows of data from two or more tables in a database. An inner join finds and returns matching data from tables, while an outer join finds and returns matching data and some dissimilar data from tables.


2 Answers

"IS NULL" and "IS NOT NULL" return a boolean, so this should make it easy.

I think this is all you need?

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

Not sure if you need the "NOT" or not, but you'll get a bool either way.

like image 120
LaVache Avatar answered Oct 31 '22 07:10

LaVache


A CASE or COALESCE statement with an outer join IS the proper way to do this.

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;
like image 35
Jordan Parmer Avatar answered Oct 31 '22 07:10

Jordan Parmer