[mysql] MySQL INNER JOIN은 두 번째 테이블에서 하나의 행만 선택합니다.

나는 users테이블과 테이블을 가지고 있으며 payments, 각 사용자에 대해 지불이있는 사용자는 payments테이블 에 여러 관련 지불이있을 수 있습니다 . 결제 한 모든 사용자를 선택하고 최근 결제 만 선택하고 싶습니다. 이 SQL을 시도하고 있지만 이전에 중첩 SQL 문을 시도한 적이 없으므로 내가 뭘 잘못하고 있는지 알고 싶습니다. 도움을 주셔서 감사합니다

SELECT u.*
FROM users AS u
    INNER JOIN (
        SELECT p.*
        FROM payments AS p
        ORDER BY date DESC
        LIMIT 1
    )
    ON p.user_id = u.id
WHERE u.package = 1



답변

에 대한 최신 날짜를 얻으려면 하위 쿼리가 필요합니다 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


답변

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
)

이 솔루션은 동일한 사용자 및 날짜로 일부 결제가있을 때 올바르게 작동하기 때문에 허용 된 답변 보다 낫습니다 .


답변

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

sqlfiddle을 확인하십시오.


답변

   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


답변

쿼리에 두 가지 문제가 있습니다.

  1. 모든 테이블과 하위 쿼리에는 이름이 필요하므로 하위 쿼리의 이름을 지정해야합니다 INNER JOIN (SELECT ...) AS p ON ....
  2. 가지고있는 하위 쿼리는 행 기간을 하나만 반환하지만 실제로 는 각 사용자에 대해 하나의 행 원합니다 . 이를 위해서는 최대 날짜를 얻기 위해 하나의 쿼리가 필요하고 전체 행을 얻기 위해 다시 자체 조인해야합니다.

에 대한 관계가 없다고 가정하면 다음을 payments.date시도하십시오.

    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


답변

@John Woo의 답변은 비슷한 문제를 해결하는 데 도움이되었습니다. 나는 올바른 순서를 설정하여 그의 대답을 개선했습니다. 이것은 나를 위해 일했습니다.

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

그래도 이것이 얼마나 효율적인지 잘 모르겠습니다.


답변

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

이것은 그것을 작동시킬 것입니다