MySQL INNER JOIN select only one row from second table

后端 未结 11 861
不知归路
不知归路 2020-11-30 21:11

I have a users table and a payments table, for each user, those of which have payments, may have multiple associated payments in the payments

相关标签:
11条回答
  • 2020-11-30 21:39

    You need to have a subquery to get their latest date per user ID.

    SELECT  a.*, c.*
    FROM users a 
        INNER JOIN payments c
            ON a.id = c.user_ID
        INNER JOIN
        (
            SELECT user_ID, MAX(date) maxDate
            FROM payments
            GROUP BY user_ID
        ) b ON c.user_ID = b.user_ID AND
                c.date = b.maxDate
    WHERE a.package = 1
    
    0 讨论(0)
  • 2020-11-30 21:40

    There are two problems with your query:

    1. Every table and subquery needs a name, so you have to name the subquery INNER JOIN (SELECT ...) AS p ON ....
    2. The subquery as you have it only returns one row period, but you actually want one row for each user. For that you need one query to get the max date and then self-join back to get the whole row.

    Assuming there are no ties for payments.date, try:

        SELECT u.*, p.* 
        FROM (
            SELECT MAX(p.date) AS date, p.user_id 
            FROM payments AS p
            GROUP BY p.user_id
        ) AS latestP
        INNER JOIN users AS u ON latestP.user_id = u.id
        INNER JOIN payments AS p ON p.user_id = u.id AND p.date = latestP.date
        WHERE u.package = 1
    
    0 讨论(0)
  • 2020-11-30 21:42

    My answer directly inspired from @valex very usefull, if you need several cols in the ORDER BY clause.

        SELECT u.* 
        FROM users AS u
        INNER JOIN (
            SELECT p.*,
             @num := if(@id = user_id, @num + 1, 1) as row_number,
             @id := user_id as tmp
            FROM (SELECT * FROM payments ORDER BY p.user_id ASC, date DESC) AS p,
                 (SELECT @num := 0) x,
                 (SELECT @id := 0) y
            )
        ON (p.user_id = u.id) and (p.row_number=1)
        WHERE u.package = 1
    
    0 讨论(0)
  • 2020-11-30 21:46

    You can try this:

    SELECT u.*, p.*
    FROM users AS u LEFT JOIN (
        SELECT *, ROW_NUMBER() OVER(PARTITION BY userid ORDER BY [Date] DESC) AS RowNo
        FROM payments  
    ) AS p ON u.userid = p.userid AND p.RowNo=1
    
    0 讨论(0)
  • 2020-11-30 21:48
    SELECT u.*, p.*, max(p.date)
    FROM payments p
    JOIN users u ON u.id=p.user_id AND u.package = 1
    GROUP BY u.id
    ORDER BY p.date DESC
    

    Check out this sqlfiddle

    0 讨论(0)
提交回复
热议问题