Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

merging two SELECT queries

Tags:

sql

mysql

I am either getting old or the queries that I need to write are getting more and more complicated. The following query will get all the tasks associated with the user.

"SELECT `date` 
   FROM `tasks` 
  WHERE `user_id`= 1;"

The tasks table is (id, date, user_id, url_id);

Now, I need to get as well records that url_id associates with the user trough the

`urls` table (`id`, `user_id`)

The standalone query would look like this:

"SELECT `t1`.`data` 
   FROM `tasks` `t1` 
   JOIN `urls` `u1` ON `u1`.`id` = `t1`.`url_id` 
  WHERE `u1`.user_id` = 1;"

Though, is it possible to merge these two queries into a single query? My logic says it should be, though I don't see how to do the actual JOIN.

like image 856
Gajus Avatar asked Jul 03 '11 14:07

Gajus


2 Answers

I'd probably use a UNION.

SELECT `date`
   FROM `tasks` WHERE `user_id`=1
UNION
SELECT `t1`.`date`
   FROM `tasks` `t1`
   INNER JOIN `urls` `u1` ON `u1`.`id` = `t1`.`url_id`
   WHERE `u1`.user_id`=1;
like image 142
tvanfosson Avatar answered Oct 05 '22 03:10

tvanfosson


You can do this in a single query:

SELECT t.date
  FROM TASKS t
 WHERE t.user_id = 1
    OR EXISTS(SELECT NULL
                FROM URLS u
               WHERE u.id = t.url_id
                 AND u.user_id = 1)

However, OR is a notoriously bad performer -- it splinters the execution plan. Splitting the query, joining the result sets can be done using the UNION or UNION ALL operators. UNION removes duplicates from the final result set; UNION ALL does not remove duplicates and is faster for it.

SELECT t.date
  FROM TASKS t
 WHERE t.user_id = 1
UNION ALL
SELECT t.date
  FROM TASKS t
 WHERE EXISTS(SELECT NULL
                FROM URLS u
               WHERE u.id = t.url_id
                 AND u.user_id = 1)

Know your data, so you know which UNION operator best serves your needs.

like image 20
OMG Ponies Avatar answered Oct 05 '22 03:10

OMG Ponies