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.*, 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.*, 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.*
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
@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
ただし、これがどれほど効率的かはわかりません。
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
また、order byはグループ化に影響を与えませんが、group byによって提供される最終結果を順序付けることができます。私はそれを試してみたが、うまくいった。
クエリには2つの問題があります。
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
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