source

MySQL INSER JOIN은 두 번째 테이블에서 행을 하나만 선택합니다.

factcode 2023. 1. 15. 17:14
반응형

MySQL INSER JOIN은 두 번째 테이블에서 행을 하나만 선택합니다.

나는 가지고 있다users테이블과 apayments지불이 있는 각 사용자에 대해 테이블에는 여러 개의 관련 지불이 있을 수 있습니다.payments테이블입니다. 결제가 있는 모든 사용자를 선택하고 싶습니다만, 최근 결제만 선택합니다.이 SQL을 사용하려고 하는데 nested 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.*
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))
)

이러한 솔루션은 사용자 및 날짜가 동일한 여러 지불이 있을 때 올바르게 작동하기 때문에 승인된 답변보다 더 좋습니다.SQL Fielen을 사용해 볼 수 있습니다.

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

얼간이 좀 봐

   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

다음과 같이 시험해 보십시오.

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

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

  1. 모든 테이블과 서브쿼리에는 이름이 필요하므로 서브쿼리 이름을 지정해야 합니다.INNER JOIN (SELECT ...) AS p ON ....
  2. 서브쿼리에서는 1개의 행 마침표만 반환되지만 실제로는 각 사용자에 대해 1개의 행이 필요합니다.그러기 위해서는 최대 날짜를 얻기 위해 하나의 쿼리가 필요하며 전체 행을 얻으려면 다시 직접 참여해야 합니다.

의 관계가 없다고 가정하면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

이것으로 동작합니다.

Matei Mihai는 단순하고 효율적인 솔루션을 제공했지만, 이 솔루션을 사용할 때까지 작동하지 않을 것입니다.MAX(date)SELECT 파트에서 이 쿼리는 다음과 같이 됩니다.

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

그리고 by순서는 그룹화에 차이가 없지만 그룹별로 최종 결과를 제공할 수 있습니다.나도 해봤는데 효과가 있었어.

ORDER BY 절에 여러 개의 콜이 필요한 경우 @valex에서 직접 영감을 받은 답변은 매우 유용합니다.

    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

이것은 매우 간단합니다. 내부 가입 후 user_id로 그룹화하고 테이블이 사용자이고 지불 쿼리가 다음과 같은 경우 payment_id에서 max aggregate 함수를 사용합니다.

SELECT user.id, max(payment.id)
FROM user INNER JOIN payment ON (user.id = payment.user_id)
GROUP BY user.id

언급URL : https://stackoverflow.com/questions/12526194/mysql-inner-join-select-only-one-row-from-second-table

반응형