简体   繁体   中英

MYSQL JOINING three table (one being itself)

I was finally able to get this (first below) query working which gives me the row of action_list_table that has the greatest value of the action_id (so it gives me that last "action" on this table per user entered)

Now I need to JOIN this with my MAIN_TABLE so I can pull info out of it too (name etc)

SELECT * FROM `action_list_table` a  

LEFT OUTER JOIN `action_list_table` b
ON (a.`record_id` = b.`record_id` AND a.`action_id` < b.`action_id`) 
WHERE a.`record_id` = '".$ID."' AND b.`record_id` IS NULL"

I tired this, but it didn't work, I'm sure I'm way off as to how to JOIN 3 tables (or as in this case JOIN one table to itself, then JOIN to another...)

"SELECT * FROM `action_list_table` a  

LEFT OUTER JOIN `MAIN_TABLE`
ON a.`record_id` = `MAIN_TABLE.ID`

LEFT OUTER JOIN `action_list_table` b
ON (a.`record_id` = b.`record_id` AND a.`action_id` < b.`action_id`) 
WHERE b.`record_id` IS NULL");

Again, I'm trying to: Find the row in the action table of each user (the user's that has the highest action_id (which would be the last one created since it's auto increment) then also pull in some of the columns from the MAIN_TABLE where the ID (record_id) on the action_list_table = the ID on the MAIN_TABLE

If your query is working the way you need it to, one option to join on the main_table is to put it in a subquery and then do your join:

SELECT * 
FROM (
    SELECT a.* 
    FROM `action_list_table` a  
        LEFT OUTER JOIN `action_list_table` b
            ON (a.`record_id` = b.`record_id` AND a.`action_id` < b.`action_id`) 
    WHERE a.`record_id` = '".$ID."' AND b.`record_id` IS NULL
   ) tablealias  
       LEFT JOIN `MAIN_TABLE`
           ON tablealias.`record_id` = `MAIN_TABLE`.`ID`

Alternatively, I'm not sure why you'd need the subquery -- you should be able to join all three tables:

SELECT * 
FROM `action_list_table` a  
     LEFT OUTER JOIN `action_list_table` b
         ON (a.`record_id` = b.`record_id` AND a.`action_id` < b.`action_id`) 
     LEFT JOIN `MAIN_TABLE`
           ON a.`record_id` = `MAIN_TABLE`.`ID`
WHERE a.`record_id` = '".$ID."' AND b.`record_id` IS NULL

Finally, as others have suggested, you could join using the MAX(Action_ID):

SELECT * 
FROM `action_list_table` a  
     INNER JOIN 
         (SELECT MAX(Action_ID) max_action_id, Record_ID
          FROM action_list_table
          GROUP BY Record_ID) t 
           ON a.action_id = t.max_action_id and a.record_id = t.record_id
     LEFT JOIN `MAIN_TABLE`
           ON a.`record_id` = `MAIN_TABLE`.`ID`
WHERE a.`record_id` = '".$ID."'

You can do this more simply by using a simple GROUP statement to get the neccesary information, ie

SELECT
    *,
    MAX(a.action_id) AS last_action_id
FROM MAIN_TABLE mt
INNER JOIN action_list_table a
ON a.record_id = mt.ID
GROUP BY mt.id

Thiis will only give you the correct value for action_id from table a though. If you want to get even more clever you could use a subquery to only get the records from action_list_table in the first place which are of interest joined onto MAIN_TABLE

SELECT
    a.*,
    MAX(a.action_id) AS last_action_id
FROM MAIN_TABLE mt

INNER JOIN (
    SELECT
        *
    FROM (
        SELECT 
            *
        FROM action_list_table
        ORDER BY action_id DESC
    ) o
    GROUP BY o.record_id
) a 
ON a.record_id = mt.ID

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