简体   繁体   中英

Show matched results with WHERE IN() first then other results- MYSQL

I have following tables:

user

id  | Name    | ...
1   | John    |
2   | Richard |
3   | Michael |

book

id  | title | author| ...
1   | ABC   |  Z    |
2   | ABM   |  X    |
3   | IJK   |  W    |
4   | MNO   |  Z    |
5   | ABQ   |  Y    |

fav_book

user_id  | book_id
1        |   5   |  
1        |   4   | 
3        |   1   | 
3        |   2   | 
3        |   5   | 

Now if John searches for a book titled Ab , I want to show his favourite book first in the search results then the others.

So output for John searching Ab should be

id  | title
5   | ABQ
1   | ABC
2   | ABM

I've tried:

SELECT * FROM (
(SELECT id, title
FROM book 
WHERE id IN(5,4) AND title LIKE 'Ab%')
UNION ALL
(SELECT id, title
FROM book )
) tbl ORDER BY ???

SO how can I manipulate my order by clause to get the desired result. Thanks.

I think you just want to tweak the order by :

SELECT id, title
FROM book 
WHERE title LIKE 'Ab%'
ORDER BY (id IN (5, 4)) DESC  -- put these first

MySQL treats a boolean like an integer in a numeric context. "true" has the value 1 and "false" 0; that is why this puts the matching ids first.

You can add another ORDER BY key to order the values in each subset (favorites and non-favorites):

ORDER BY (id IN (5, 4)) DESC,  -- put these first
         id

I guess you don't want to hardcode the fav books for each user.
If you want the results for user_id = 1 and search for title beginning with 'Ab' :

select 
  id, title
from book 
where title like 'Ab%'
order by (
  case when id in (select book_id from fav_book where user_id = 1) then 0
  else 1 end
), title

See the demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM