MySQL INNER JOIN select only one row from second table

后端 未结 11 860
不知归路
不知归路 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:24
       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 payments AS p,
                     (SELECT @num := 0) x,
                     (SELECT @id := 0) y
                ORDER BY p.user_id ASC, date DESC)
            ON (p.user_id = u.id) and (p.row_number=1)
            WHERE u.package = 1
    
    0 讨论(0)
  • 2020-11-30 21:25
    SELECT u.*, p.*
    FROM users AS u
    INNER JOIN payments AS p ON p.id = (
        SELECT id
        FROM payments AS p2
        WHERE p2.user_id = u.id
        ORDER BY date DESC
        LIMIT 1
    )
    

    Or

    SELECT u.*, p.*
    FROM users AS u
    INNER JOIN payments AS p ON p.user_id = u.id
    WHERE NOT EXISTS (
        SELECT 1
        FROM payments AS p2
        WHERE
            p2.user_id = p.user_id AND
            (p2.date > p.date OR (p2.date = p.date AND p2.id > p.id))
    )
    

    This solutions are better than the accepted answer because they work correctly when there are multiple payments with same user and date. You can try on SQL Fiddle.

    0 讨论(0)
  • 2020-11-30 21:31

    This is quite simple do The inner join and then group by user_id and use max aggregate function in payment_id assuming your table being user and payment query can be

    select user.id, max(payment.id) from user inner join payment on (user.id = payment.user_id) group by user.id

    0 讨论(0)
  • 2020-11-30 21:32

    @John Woo's answer helped me solve a similar problem. I've improved upon his answer by setting the correct ordering as well. This has worked for me:

    SELECT  a.*, c.*
    FROM users a 
        INNER JOIN payments c
            ON a.id = c.user_ID
        INNER JOIN (
            SELECT user_ID, MAX(date) as maxDate FROM
            (
                SELECT user_ID, date
                FROM payments
                ORDER BY date DESC
            ) d
            GROUP BY user_ID
        ) b ON c.user_ID = b.user_ID AND
               c.date = b.maxDate
    WHERE a.package = 1
    

    I'm not sure how efficient this is, though.

    0 讨论(0)
  • 2020-11-30 21:36
    SELECT U.*, V.* FROM users AS U 
    INNER JOIN (SELECT *
    FROM payments
    WHERE id IN (
    SELECT MAX(id)
    FROM payments
    GROUP BY user_id
    )) AS V ON U.id = V.user_id
    

    This will get it working

    0 讨论(0)
  • 2020-11-30 21:36

    Matei Mihai given a simple and efficient solution but it will not work until put a MAX(date) in SELECT part so this query will become:

    SELECT u.*, p.*, max(date)
    FROM payments p
    JOIN users u ON u.id=p.user_id AND u.package = 1
    GROUP BY u.id
    

    And order by will not make any difference in grouping but it can order the final result provided by group by. I tried it and it worked for me.

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