Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joining a list of values with table rows in SQL

Suppose I have a list of values, such as 1, 2, 3, 4, 5 and a table where some of those values exist in some column. Here is an example:

id  name  1  Alice  3  Cindy  5  Elmore  6  Felix 

I want to create a SELECT statement that will include all of the values from my list as well as the information from those rows that match the values, i.e., perform a LEFT OUTER JOIN between my list and the table, so the result would be like follows:

id  name  1  Alice  2  (null)  3  Cindy  4  (null)  5  Elmore 

How do I do that without creating a temp table or using multiple UNION operators?

like image 796
uncoder Avatar asked Apr 29 '14 23:04

uncoder


People also ask

How do you join rows in SQL?

SQL JOIN. A JOIN clause is used to combine rows from two or more tables, based on a related column between them. Notice that the "CustomerID" column in the "Orders" table refers to the "CustomerID" in the "Customers" table. The relationship between the two tables above is the "CustomerID" column.

How do I join an array in SQL?

This is the function to use if you want to concatenate all the values in an array field into one string value. You can specify an optional argument as a separator, and it can be any string. If you do not specify a separator, there will be nothing aded between the values.

What are the 4 different table joining types?

There are four main types of JOINs in SQL: INNER JOIN, OUTER JOIN, CROSS JOIN, and SELF JOIN.

Which join can be used to join entries from two tables so that each row in each table has a match?

The simplest kind of join we can do is a CROSS JOIN or "Cartesian product." This join takes each row from one table and joins it with each row of the other table. Each value from the first list is paired with each value of the second list.


2 Answers

If in Microsoft SQL Server 2008 or later, then you can use Table Value Constructor

 Select v.valueId, m.name   From (values (1), (2), (3), (4), (5)) v(valueId)      left Join otherTable m         on m.id = v.valueId 

Postgres also has this construction VALUES Lists:

SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter) 

Also note the possible Common Table Expression syntax which can be handy to make joins:

WITH my_values(num, str) AS (     VALUES (1, 'one'), (2, 'two'), (3, 'three') ) SELECT num, txt FROM my_values 

With Oracle it's possible, though heavier From ASK TOM:

with id_list as (   select 10 id from dual union all   select 20 id from dual union all   select 25 id from dual union all   select 70 id from dual union all   select 90 id from dual )   select * from id_list; 
like image 102
Charles Bretana Avatar answered Sep 22 '22 13:09

Charles Bretana


the following solution for oracle is adopted from this source. the basic idea is to exploit oracle's hierarchical queries. you have to specify a maximum length of the list (100 in the sample query below).

   select d.lstid         , t.name      from (                select substr(                            csv                          , instr(csv,',',1,lev) + 1                          , instr(csv,',',1,lev+1 )-instr(csv,',',1,lev)-1                       )  lstid                  from (select ','||'1,2,3,4,5'||',' csv from dual)                     , (select level lev from dual connect by level <= 100)                 where lev <= length(csv)-length(replace(csv,','))-1                    ) d left join test  t on ( d.lstid = t.id )         ; 

check out this sql fiddle to see it work.

like image 41
collapsar Avatar answered Sep 23 '22 13:09

collapsar