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
쿼리에는 다음 두 가지 문제가 있습니다.
- 모든 테이블과 서브쿼리에는 이름이 필요하므로 서브쿼리 이름을 지정해야 합니다.
INNER JOIN (SELECT ...) AS p ON ...
. - 서브쿼리에서는 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
'source' 카테고리의 다른 글
Vuetify 배지가 표시되지 않음 - 컴파일된 코드로 코멘트 아웃됨 (0) | 2023.01.15 |
---|---|
.format을 사용하는 동안 문자열에 괄호로 묶은 문자를 인쇄하려면 어떻게 해야 합니까? (0) | 2023.01.15 |
HikariPool-1 - 연결 획득 중 중단됨 (0) | 2023.01.15 |
순간의 언어를 변경하려면 어떻게 해야 합니까? (0) | 2023.01.15 |
JVM은 테일콜 최적화를 방해합니까? (0) | 2023.01.15 |