简体   繁体   中英

MySQL UNION ALL with LEFT JOIN

I am trying to work out the most efficient query to put data from two tables into one set of results and left join the user data to it. I need help with the syntax for the query. I have put together the below but it's not quite right.

$query_chat = sprintf("SELECT comment_id, user_id, comment, timestamp FROM activity 
UNION ALL
SELECT comment_id, user_id, comment, timestamp FROM comments
LEFT JOIN users.company, users.contact_person, users.email ON users.user_id = comments.user_id
WHERE user_id = %s
ORDER BY timestamp DESC", GetSQLValueString($_GET['comment_id'], "INT"));

The syntax is wrong and throws up the below - I am trying to make it efficient by only selecting what I need from the users table.

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' users.contact_person, users.email ON users.user_id = comments.user_id WHERE us' at line 4

I have now got to this point below but get Unknown column 'users.company' in 'field list'

SELECT
    comments.comment_id, comments.user_id, comments.comment,
    comments.timestamp,
    users.company, users.contact_person, users.email
FROM
    comments
UNION ALL
SELECT
    activity.comment_id, activity.user_id, activity.comment,
    activity.timestamp, 
    users.company, users.contact_person, users.email
FROM
    activity
LEFT JOIN users ON users.user_id = comments.user_id
WHERE
comments.comment_id = 69 ORDER BY timestamp ASC

Here is your problem:

LEFT JOIN
    users.company, users.contact_person, users.email
    ON users.user_id = comments.user_id

The syntax is:

LEFT JOIN (table) ON (join-clause)

So, in your case, I think you need something like this:

SELECT
    comments.comment_id, comments.user_id, comments.comment,
    comments.timestamp,
    users.company, users.contact_person, users.email
FROM
    comments
    LEFT JOIN users ON users.user_id = comments.user_id
WHERE
    users.user_id = %s
;

As you can see, when using a JOIN , the columns come first (from all tables) and then the tables come next, with their corresponding JOIN clauses.


Update: in reply to your update, you have two options. You can do this (which you are closest to):

SELECT
    (users joined to activity)
UNION
    (users joined to comments)

You already know how to do the (expressions) above - see the earlier part of my answer. Or, you can do things this way:

SELECT
    *
FROM
    (SELECT * FROM activity UNION SELECT * FROM comments) user_actions
    LEFT JOIN users ON (users.user_id = user_actions.user_id)

Note that in both examples cases in this update, I am offering pseudocode 1 - you need to fill in the blanks. You'll find that the skill of taking a generalised example (say from a manual) and applying to your own use case is something that happens a great deal in computer science, so you should practice this as often as possible.

1 That said, the second version containing the sub-query is done except for changing the columns to fetch - so you are probably 95% of the way there!

So finally got there with the below, appreciate the direction halfer

SELECT
    comments.*, users.company, users.contact_person, users.email
    FROM
        comments
    LEFT JOIN users ON users.user_id = comments.user_id
    WHERE
        comment_id = %s
UNION ALL
SELECT activity.*, users.company, users.contact_person, users.email
    FROM
        activity
    LEFT JOIN users ON users.user_id = activity.user_id
    WHERE
        comment_id = %s
ORDER BY
    timestamp ASC

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