简体   繁体   中英

MYSQL UNION ORDER BY

I currently have this

SELECT  *
FROM    images
WHERE   images.id IN (SELECT image_id FROM image_likes WHERE user_id = '1')
    UNION
SELECT * 
FROM images
WHERE images.user_id = '1' AND upload_type in (4,3) ORDER BY id DESC

And this works great, but now i want it to display the most recent results thats have happend. For example, User A uploaded a image-> information goes into images with a timestamp. User A then likes someone else's image -> Information goes into image_likes with a timestamp. Now how would i make the two timestamp column's merge together so i can sort them by DESC.

Breif run over of what the query does. Selects the image information from images where the user has liked a image in image_likes and then it grabs all of the uploads the user has uploaded from images and merges them into a query. What i need is to be able to sort them using the timestamp from both tables.

how about doing this??

SELECT * FROM (
    SELECT  *
    FROM    images
    WHERE   images.id IN (SELECT image_id FROM image_likes WHERE user_id = '1')
        UNION
    SELECT * 
    FROM images
    WHERE images.user_id = '1' AND upload_type in (4,3) ORDER BY id DESC
) AS a ORDER BY a.timestamp DESC;

OR even better

 (SELECT  *
    FROM images
    WHERE images.id IN (SELECT image_id FROM image_likes WHERE user_id = '1'))
        UNION
 (SELECT * 
    FROM images
    WHERE images.user_id = '1' AND upload_type in (4,3) ORDER BY id DESC)
 ORDER BY timestamp DESC

chk this http://dev.mysql.com/doc/refman/5.5/en/union.html

UPDATE

TRY THIS

 (SELECT images.id, images_likes.timestamp as timestamp FROM images JOIN images_likes 
    ON images.id=image_likes.image_id WHERE user_id = '1')
        UNION
 (SELECT images.id, images.timestamp as timestamp
    FROM images
    WHERE images.user_id = '1' AND upload_type in (4,3) ORDER BY id DESC)
 ORDER BY timestamp DESC

UPDATE

Final query as per your requirement

 (SELECT images.id, images.user_id, images.ext, images.upload_type, images_likes.timestamp as timestamp FROM images JOIN images_likes 
    ON images.id=image_likes.image_id WHERE images_likes.user_id = '1')
        UNION
 (SELECT images.id, images.user_id, images.ext, images.upload_type, images.timestamp as timestamp
    FROM images
    WHERE images.user_id = '1' AND upload_type in (4,3) ORDER BY id DESC)
 ORDER BY timestamp DESC

I would approach with the following... The "PreQuery" below starts with all images the user likes first, with the max timestamp as a new column "MostRecent". THEN, do a UNION ALL for the next set. The next set is directly from the images table for the user, but LEFT JOINED to the "Liked" images. Then the WHERE clause explicitly excludes those that would have been returned in the first set by using the "iml2.image_id IS NULL". I did this as I wasn't positive on how the union would handle the group by in the first set, but no group by in the second. Ex: If the image was created with date/timestamp of say Mar 3, but also found as a "Like" of Mar 5, I didn't want one instance listed as each distinct date (as union already qualifies distinct implied).

That said, I will have a single prequery result of any image the person liked with its most recent date/time stamp, AND all their own personal images with their respective date/time stamp. Now, its a simple join back to the images table to grab the details (via alias "i2") and we can sort by the PreQuery.MostRecent column, then by the image ID value descending.

SELECT
      i2.*
   from
      ( select iml.image_id as id,
               max( iml.YourTimeStamp ) as MostRecent
           from image_likes iml
           where iml.user_id = '1'
           group by iml.image_id

        UNION ALL

        select i.id,
               i.ImageTimeStamp as MostRecent
           from images i
              left join image_likes iml2
                 on i.id = iml2.image_id
                 and iml2.user_id = '1'
           where i.user_id = '1'
             and i.upload_type in ( 4, 3 )
             and iml2.image_id is null 
      ) PreQuery
         JOIN Images i2
            on PreQuery.id = i2.id
   order by
      PreQuery.MostRecent,
      PreQuery.ID desc

Why don't you use a 'OR'?

that way :

  SELECT  *
  FROM    images
  WHERE   images.id IN (SELECT image_id FROM image_likes WHERE user_id = '1')
      OR  (images.user_id = '1' AND upload_type in (4,3))
 ORDER BY id DESC
SELECT *
FROM 
  ( SELECT  im.*
          , li.timestamp AS ts
    FROM    images AS im 
      JOIN  image_likes AS li
        ON  li.image_id = im.image_id
    WHERE   li.user_id = 1
  UNION ALL
    SELECT *
         , timestamp AS ts
    FROM images 
    WHERE user_id = 1 
      AND upload_type in (4,3) 
  ) AS tmp
ORDER BY ts DESC

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