ユーザーの現在のIPと1つ以上の以前のIPの両方を含むテーブルから、IP、ユーザー、および最新のタイムスタンプを取得しようとしています。最新のIPと関連するタイムスタンプを含むユーザーごとに1行が必要です。したがって、テーブルが次のようになっている場合:
username | ip | time_stamp
--------------|----------|--------------
ted | 1.2.3.4 | 10
jerry | 5.6.6.7 | 12
ted | 8.8.8.8 | 30
クエリの出力は次のようになります。
jerry | 5.6.6.7 | 12
ted | 8.8.8.8 | 30
これを単一のSQLクエリで実行できますか?重要な場合、DBMSはPostgresqlです。
これを試して:
Select u.[username]
,u.[ip]
,q.[time_stamp]
From [users] As u
Inner Join (
Select [username]
,max(time_stamp) as [time_stamp]
From [users]
Group By [username]) As [q]
On u.username = q.username
And u.time_stamp = q.time_stamp
ROW_NUMBERウィンドウ関数を使用したエレガントなソリューション(PostgreSQLでサポート-SQL Fiddleを参照):
SELECT username, ip, time_stamp FROM (
SELECT username, ip, time_stamp,
ROW_NUMBER() OVER (PARTITION BY username ORDER BY time_stamp DESC) rn
FROM Users
) tmp WHERE rn = 1;
このようなもの:
select *
from User U1
where time_stamp = (
select max(time_stamp)
from User
where username = U1.username)
それを行う必要があります。
上記の答えは両方とも、各ユーザーとtime_stampに対して1行しかないことを前提としています。アプリケーションとtime_stampの粒度によっては、これは有効な仮定ではない場合があります。特定のユーザーのtime_stampの関係を処理する必要がある場合は、上記の回答のいずれかを拡張する必要があります。
これを1つのクエリで記述するには、別のネストされたサブクエリが必要になります-物事がさらに面倒になり、パフォーマンスが低下する可能性があります。
これをコメントとして追加したかったのですが、まだ50の評判はありませんので、新しい回答として投稿してすみません!
まだコメントを投稿することはできませんが、@ Cristi Sの答えは私にとってはうまいことです。
私のシナリオでは、すべてのproduct_idについて、Lowest_Offersの最新の3レコードのみを保持する必要がありました。
SQLを削除して削除する必要があります-これは問題ないと思いますが、構文が間違っています。
DELETE from (
SELECT product_id, id, date_checked,
ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY date_checked DESC) rn
FROM lowest_offers
) tmp WHERE > 3;
別のテーブルから結果を返すため、これを使用しています。ネストされた結合を回避しようとしていますが、ステップが1つ減ると役立ちます。しかたがない。同じものを返します。
select
users.userid
, lastIP.IP
, lastIP.maxdate
from users
inner join (
select userid, IP, datetime
from IPAddresses
inner join (
select userid, max(datetime) as maxdate
from IPAddresses
group by userid
) maxIP on IPAddresses.datetime = maxIP.maxdate and IPAddresses.userid = maxIP.userid
) as lastIP on users.userid = lastIP.userid