我有一个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
答案 0 :(得分:110)
您需要有一个子查询才能获得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
答案 1 :(得分:10)
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
答案 2 :(得分:7)
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
)
此解决方案比accepted answer更好,因为当某些付款使用相同的用户和日期时,它可以正常工作。
答案 3 :(得分:3)
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
答案 4 :(得分:2)
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
这将使其正常工作
答案 5 :(得分:1)
您的查询存在两个问题:
INNER JOIN (SELECT ...) AS p ON ...
。 假设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
答案 6 :(得分:1)
Matei Mihai给出了一个简单而有效的解决方案但是在SELECT部分放置MAX(date)
之后它将无效,因此该查询将成为:
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
顺序不会对分组产生任何影响,但它可以命令分组提供的最终结果。我试过了,它对我有用。
答案 7 :(得分:1)
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
我不确定这是多么有效率。
答案 8 :(得分:0)
如果在ORDER BY子句中需要多个cols,我的答案直接受到@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
答案 9 :(得分:0)
您可以尝试以下方法:
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
答案 10 :(得分:0)
这很简单:假设您的表是用户,并且付款查询可以是
,那么先进行内部联接,然后按user_id分组,并在payment_id中使用max汇总函数。 select user.id, max(payment.id) from user inner join payment on (user.id = payment.user_id) group by user.id