Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I combine two queries on the same table to get a single result set in MySQL

I am not very good at sql but I am getting there. I have searched stackoverflow but I can't seem to find the solution and I hope someone out there can help me. I have a table (users) with data like the following. The book_id column is a key to another table that contains a book the user is subscribed to.

|--------|---------------------|------------------|
|   id   |      book_id        |       name       |
|--------|---------------------|------------------|
|   1    |         1           |        jim       |
|   2    |         1           |       joyce      |
|   3    |         1           |        mike      |
|   4    |         1           |       eleven     |
|   5    |         2           |        max       |
|   6    |         2           |       dustin     |
|   7    |         2           |       lucas      |
|--------|---------------------|------------------|

I have a function in my PHP code that returns two random users from a specific book id (either 1 or 2). Query one returns the result in column 1 and result two returns the results in column 2 like:

|---------------------|------------------|
|          1          |        2         |
|---------------------|------------------|
|        jim          |       max        |
|       joyce         |     dustin       |
|---------------------|------------------|

I have achieved this by running two separate queries as seen below. I want to know if it's possible to achieve this functionality with one query and how.

$random_users_with_book_id_1 = SELECT name FROM users WHERE book_id=1 LIMIT 2
$random_users_with_book_id_2 = SELECT name FROM users WHERE book_id=2 LIMIT 2

Again, I apologise if it's too specific. The query below has been closest to what I was trying to achieve.:

SELECT a.name AS book_id_1, b.name AS book_id_2   
FROM users a, users b 
WHERE a.book_id=1 AND b.book_id = 2
LIMIT 2

EDIT: I have created a fiddle to play around with his. I appreciate any help! Thank you!! http://sqlfiddle.com/#!9/7fcbca/1

like image 267
realnsleo Avatar asked Jan 29 '23 06:01

realnsleo


2 Answers

It is easy actually :)

you can use UNION like this:

SELECT * FROM (
     (SELECT * FROM user WHERE n_id=1 LIMIT 2)
     UNION
     (SELECT * FROM user WHERE n_id=2 LIMIT 2)) 
 collection;

if you read this article about the documentation you can use the () to group the individual queries and the apply the union in the middle. Without the parenthesis it would still LIMIT 2 and show only the two first. Ref. "To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:"

like image 65
oetoni Avatar answered Feb 01 '23 00:02

oetoni


If you want to combine the queries in MySQL, you can just use parentheses:

(SELECT name
 FROM users
 WHERE n_id = 1
 LIMIT 2
) UNION ALL
(SELECT name
 FROM users
 WHERE n_id = 2
 LIMIT 2
);

First, only use UNION if you specifically want to incur the overhead of removing duplicates. Otherwise, use UNION ALL.

Second, this does not return random rows. This returns arbitrary rows. In many cases, this might be two rows near the beginning of the data. If you want random rows, then use ORDER BY rand():

(SELECT name
 FROM users
 WHERE n_id = 1
 ORDER by rand()
 LIMIT 2
) UNION ALL
(SELECT name
 FROM users
 WHERE n_id = 2
 ORDER BY rand()
 LIMIT 2
);

There are other methods that are more efficient, but this should be fine for up to a few thousand rows.

like image 42
Gordon Linoff Avatar answered Feb 01 '23 00:02

Gordon Linoff