ユーザーがいつログオンしたかに関するコレクションエントリであるテーブルがあります。
username, date, value
--------------------------
brad, 1/2/2010, 1.1
fred, 1/3/2010, 1.0
bob, 8/4/2009, 1.5
brad, 2/2/2010, 1.2
fred, 12/2/2009, 1.3
etc..
各ユーザーの最新の日付を表示するクエリを作成する方法を教えてください。
更新:最新の日付に沿った値を設定する必要があることを忘れました。
select t.username, t.date, t.value
from MyTable t
inner join (
select username, max(date) as MaxDate
from MyTable
group by username
) tm on t.username = tm.username and t.date = tm.MaxDate
ウィンドウ関数を使用する(Oracle、Postgres 8.4、SQL Server 2005、DB2、Sybase、Firebird 3.0、MariaDB 10.3で動作します)
select * from (
select
username,
date,
value,
row_number() over(partition by username order by date desc) as rn
from
yourtable
) t
where t.rn = 1
大部分の開発者は、巨大なデータへの影響を考慮せずにインラインクエリを使用しています。
簡単に言うと、これを達成することができます。
SELECT a.username, a.date, a.value
FROM myTable a
LEFT OUTER JOIN myTable b
ON a.username = b.username
AND a.date < b.date
WHERE b.username IS NULL
ORDER BY a.date desc;
ユーザーの最大日付を含む行全体を取得するには、次の手順を実行します。
select username, date, value
from tablename where (username, date) in (
select username, max(date) as date
from tablename
group by username
)
SELECT *
FROM MyTable T1
WHERE date = (
SELECT max(date)
FROM MyTable T2
WHERE T1.username=T2.username
)
これにより、編集した質問に対して正しい結果が得られます。
サブクエリは必ず最新の日付の行だけを見つけるようにし、外側のGROUP BY
は関係を処理します。同じユーザーの同じ日付に2つのエントリがある場合は、最も高いvalue
を持つエントリが返されます。
SELECT t.username, t.date, MAX( t.value ) value
FROM your_table t
JOIN (
SELECT username, MAX( date ) date
FROM your_table
GROUP BY username
) x ON ( x.username = t.username AND x.date = t.date )
GROUP BY t.username, t.date
分析ランク関数も使用できます
with temp as
(
select username, date, RANK() over (partition by username order by date desc) as rnk from t
)
select username, rnk from t where rnk = 1
私の経験上、最も早い方法は、テーブルに新しい行がない各行を取得することです。これは私が手元にあるいくつかのデータを使った小さなベンチマークです。
もう1つの利点は、使用される構文が非常に単純であること、およびクエリの意味がかなり把握しやすいことです(検討対象のユーザー名に対して新しい行が存在しないようにすべての行を取得する)。
SELECT username, value
FROM t
WHERE NOT EXISTS (
SELECT *
FROM t AS witness
WHERE witness.date > t.date
);
説明費用の合計:2.38136
SELECT username, value
FROM (
SELECT username, value, row_number() OVER (PARTITION BY username ORDER BY date DESC) AS rn
FROM t
) t2
WHERE rn = 1
トータルコスト:61.5823
SELECT t.username, t.value
FROM t
INNER JOIN (
SELECT username, MAX(date) AS date
FROM t
GROUP BY username
) tm ON t.username = tm.username AND t.date = tm.date;
説明費用合計:67.5439
SELECT username, value
FROM t
LEFT OUTER JOIN t AS w ON t.username = w.username AND t.date < w.date
WHERE w.username IS NULL
説明費用の合計:62.964
EXPLAIN PLANは、XMLとして格納された約1万行のデータベースから取得されます。使用されるクエリには、述語 "group_id = '1'"も含まれています。
Select * from table1 where lastest_date=(select Max(latest_date) from table1 where user=yourUserName)
Inner Queryは現在のユーザーの最新の日付を返します。Outerqueryは、内部クエリの結果に従ってすべてのデータを取得します。
Oracleの場合、結果セットは降順でソートされ、最初のレコードが取得されるため、最新のレコードが取得されます。
select * from mytable
where rownum = 1
order by date desc
この方法を使用して、自分のテーブルにある各ユーザーの最後のレコードを取得しました。 PDAデバイスで最近検出された時間に、セールスマンの最後の場所を取得するためのクエリでした。
CREATE FUNCTION dbo.UsersLocation()
RETURNS TABLE
AS
RETURN
Select GS.UserID, MAX(GS.UTCDateTime) 'LastDate'
From USERGPS GS
where year(GS.UTCDateTime) = YEAR(GETDATE())
Group By GS.UserID
GO
select gs.UserID, sl.LastDate, gs.Latitude , gs.Longitude
from USERGPS gs
inner join USER s on gs.SalesManNo = s.SalesmanNo
inner join dbo.UsersLocation() sl on gs.UserID= sl.UserID and gs.UTCDateTime = sl.LastDate
order by LastDate desc
SELECT t1.username, t1.date, value
FROM MyTable as t1
INNER JOIN (SELECT username, MAX(date)
FROM MyTable
GROUP BY username) as t2 ON t2.username = t1.username AND t2.date = t1.date
SELECT *
FROM ReportStatus c
inner join ( SELECT
MAX(Date) AS MaxDate
FROM ReportStatus ) m
on c.date = m.maxdate
SELECT * FROM TABEL1 WHERE DATE= (SELECT MAX(CREATED_DATE) FROM TABEL1)
SELECT Username, date, value
from MyTable mt
inner join (select username, max(date) date
from MyTable
group by username) sub
on sub.username = mt.username
and sub.date = mt.date
更新された問題に対処します。優れた索引付けがあっても、大きなテーブルではそれほどうまくいかないかもしれません。
これは上記の答えの1つに似ていますが、私の意見ではそれははるかに単純で整頓されています。また、クロス適用ステートメントの有用な使用方法を示しています。 SQL Server 2005以降の場合.
select
a.username,
a.date,
a.value,
from yourtable a
cross apply (select max(date) 'maxdate' from yourtable a1 where a.username=a1.username) b
where a.date=b.maxdate
私の小さなコンピレーション
join
よりもself select
の方が優れていますgroup by
はprimary key
を与えません。これはjoin
には望ましいですpartition by
と組み合わせてfirst_value
で指定できます( docs )だから、これはクエリです:
から t。* を選択します。Table t内部結合( を選択します。 FilterColumn = 'value'からID としてID t.ID = j.ID
長所:
where
ステートメントでデータをフィルター処理するselect
フィルター処理された行の任意の列短所:
私はそれが私のアプリケーションのためにややしました:
以下はそのクエリです。
select distinct i.userId,i.statusCheck, l.userName from internetstatus
as i inner join login as l on i.userID=l.userID
where nowtime in((select max(nowtime) from InternetStatus group by userID));