Question

I'm trying to create a user favorites system but having a difficult time creating a query that accomplishes what I need. I'll use fruits as an example.

First, here's my fruitsinfo table:

        id     |   color   |    rating
      apples        red          8.4
      oranges      orange        9.1
   blueberries      blue         8.8
    pineapple      yellow        7.9
      peaches      orange        8.3

Then there's the currentfruit table, which lists only fruits that are in season and has their current market price (this data is hilariously bad, but bear with me):

        id     |  price   |   months left in season
    apples         1.25            6
    avocados       1.42            4
    pears          1.24            3
    oranges        1.75            5
    blueberries    2.20            4

Lastly, a userfavorites table, which contains the userid and fruit id:

      userid  |   fruitid
        5          apples
        5          peaches
        5           pears

We'll just be working with the user with userid = '5'. A couple things to note here: not all the entries in currentfruits are in fruitsinfo and not all the entries in userfavorites are in currentfruits.

When the users usually access the site with no favorites saved, they just see currentfruits left joined with fruitsinfo and ordered by price, like so:

   id     |  price   |   months left in season  | color  | rating 
blueberries   2.20                  4              blue    8.8
  oranges     1.75                  5             orange   9.1
  avocados    1.42                  4              null    null
  apples      1.25                  6              red     8.4
   pears      1.24                  3              null    null

Now, what I want is for there to be a check to see if any of user's favorite fruits are in the currentfruits table, then list those results first (ordered by price), then the rest of the currentfruits (ordered by price). Our user has apples, pears, and peaches as favorites, but only apples and pears are in currentfruits, so the table should now look like:

   id     |  price   |   months left in season  | color  | rating 
  apples      1.25                  6              red     8.4
   pears      1.24                  3              null    null
blueberries   2.20                  4              blue    8.8
  oranges     1.75                  5             orange   9.1
  avocados    1.42                  4              null    null

My initial thought was to do something like this:

SELECT * 
FROM userfavorites
JOIN currentfruits ON userfavorites.fruitid = currentfruits.id
JOIN fruitsinfo ON currentfruits.id = fruitsinfo.id
ORDER BY currentfruits.price DESC

UNION

SELECT *
FROM currentfruits
LEFT JOIN fruitsinfo ON currentfruits.id = fruitsinfo.id
ORDER BY currentfruits.price DESC

The first SELECT grabs the first two rows of the desired table and the second SELECT grabs the entire table that a user would see without favorites. Unfortunately this didn't just slam the rows together like I hoped. Also because UNION only deals with distinct entries, I was hoping that would take care of the duplicate rows that might show up with the bottom select, but alas.

Can anyone tell me how I might go about making a query that accomplishes what I'm wanting to do? Thanks.

Was it helpful?

Solution

You don't have to use a UNION. Try:

select c.id, c.price, c.`months left in season`, i.color, i.rating 
from currentfruit c
left join fruitsinfo i on c.id = i.id
left join userfavorites f on c.id = f.id and f.userid = 5
order by case when f.id is not null then 0 else 1 end, c.price desc
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top