列の最大値を持つ行をフェッチします


575

テーブル:

UserId, Value, Date.

UserId、各UserIdのmax(Date)の値を取得したい。つまり、最新の日付を持つ各UserIdの値です。これをSQLで簡単に行う方法はありますか?(できればOracle)

更新:あいまいさをお詫びします:すべてのユーザーIDを取得する必要があります。ただし、各UserIdについては、そのユーザーが最新の日付を持っている行のみ。


21
特定のユーザーIDの最大日付値を持つ複数の行がある場合はどうなりますか?
David Aldridge

テーブルの主要なフィールドは何ですか?
vamosrafa 2013年

以下のいくつかのソリューションを比較:sqlfiddle.com
#

1
@DavidAldridge、その列はおそらく一意です。
Pacerier 2015

回答:


398

これにより、my_date列の値がそのユーザーIDのmy_dateの最大値と等しいすべての行が取得されます。これにより、最大日付が複数の行にあるユーザーIDの複数の行が取得される場合があります。

select userid,
       my_date,
       ...
from
(
select userid,
       my_date,
       ...
       max(my_date) over (partition by userid) max_my_date
from   users
)
where my_date = max_my_date

「分析機能は素晴らしい」

編集:最初のコメントに関して...

「分析クエリと自己結合を使用すると、分析クエリの目的が無効になります」

このコードには自己結合はありません。代わりに、分析関数を含むインラインビューの結果に述語が配置されます。これは、非常に異なる問題であり、完全に標準的な方法です。

「Oracleのデフォルトウィンドウは、パーティションの最初の行から現在の行までです。」

ウィンドウ句は、order by句が存在する場合にのみ適用されます。order by句がない場合、デフォルトではウィンドウ句は適用されず、明示的に指定することはできません。

コードは機能します。


39
880万行のテーブルに適用した場合、このクエリは、投票数の多い他の回答のクエリの半分の時間しかかかりませんでした。
Derek Mahar、2011

4
これに相当するMySQLへのリンクを投稿したいと思う人はいますか?
2015年

2
これは重複を返すことができませんでしたか?例えば。2つの行に同じuser_idと同じ日付がある場合(たまたま最大になります)。
jastr 2016年

2
@jastr私はそれが質問で認められたと思います
David Aldridge

3
代わりに(グループごとのトップn)または(グループごとの最大n )をMAX(...) OVER (...)使用することもできます。ROW_NUMBER() OVER (...)RANK() OVER (...)
MT0 2016年

441

多くの人がサブクエリやベンダー固有の機能を使用してこれを実行しているようですが、サブクエリなしでこの種のクエリを次のように実行することがよくあります。プレーンな標準SQLを使用しているため、RDBMSのどのブランドでも機能します。

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON (t1.UserId = t2.UserId AND t1."Date" < t2."Date")
WHERE t2.UserId IS NULL;

つまりt1、同じUserIdでより大きい日付を持つ他の行が存在しない場所から行をフェッチします。

(識別子 "Date"はSQL予約語であるため、区切り文字で囲みます。)

の場合t1."Date" = t2."Date"、倍増が表示されます。通常、テーブルにはauto_inc(seq)キーがありますid。重複を回避するには、次のように使用できます。

SELECT t1.*
FROM mytable t1
  LEFT OUTER JOIN mytable t2
    ON t1.UserId = t2.UserId AND ((t1."Date" < t2."Date") 
         OR (t1."Date" = t2."Date" AND t1.id < t2.id))
WHERE t2.UserId IS NULL;

@Farhanからの再コメント:

詳細は次のとおりです。

外部結合はとの結合t1を試みt2ます。デフォルトでは、すべての結果がt1返され、そして場合試合はでありt2、それも返されます。のt2特定の行に一致するものがない場合t1でも、クエリはの行を返し、すべてののプレースホルダーとしてt1使用NULLします。t2の列のます。これが、一般的に外部結合が機能する方法です。

このクエリの秘訣はt2同じ useridより大きいに 一致するように結合の一致条件を設計することdateです。その中に行が存在する場合、その行がt2より大きいdate場合、t1比較される行はその中で最大になることはできません。しかし、一致がない場合-つまりは何の行が中に存在しない場合は大きいとして、行よりも、我々は内の行があることを知っている- 最大で行だった与えられたため。dateuseridt2datet1t1dateuserid

それらの場合(一致がない場合)の列は、結合条件で指定された列であってt2NULL-になります。そのWHERE t2.UserId IS NULLため、を使用するのはそのためです。date指定されたでより大きい行が見つからなかった場合を検索しているからですuserid


7
すごいビル。これは私が見たこの問題に対する最も創造的な解決策です。かなり大きなデータセットでも、かなりパフォーマンスが高くなります。これは、私が見た他の多くの解決策や、この難題を解決するための私自身の試みに勝るものです。
Justin Noel

37
このクエリを880万行のテーブルに適用すると、受け入れられた回答のクエリのほぼ2倍の時間がかかりました。
Derek Mahar

16
@Derek:最適化は、RDBMSのブランドとバージョン、および適切なインデックス、データ型などの存在に依存します
ビルKarwin

7
MySQLでは、この種のクエリが実際にテーブル間のデカルト結合の結果をループさせ、O(n ^ 2)時間をもたらすようです。代わりにサブクエリメソッドを使用すると、クエリ時間が2.0秒から0.003秒に短縮されました。YMMV。
ジェシー

1
これを、日付がユーザーの指定した日付以下の最大の日付である行に一致するように調整する方法はありますか?たとえば、ユーザーが日付「23-OCT-2011」を指定し、テーブルに「24-OCT-2011」、「22-OCT-2011」、「20-OCT-2011」の行が含まれている場合、 「2011年10月22日」を取得します。頭をかいて、このスニペットをしばらく読んでいます...
Cory Kendall

164
SELECT userid, MAX(value) KEEP (DENSE_RANK FIRST ORDER BY date DESC)
  FROM table
  GROUP BY userid

3
多数の行を持つテーブルを使用したテストでは、この解決策は、受け入れられた回答の約2倍の時間がかかりました。
Derek Mahar、2011

7
テストを見せてください
Rob van Wijk

他のソリューションよりもはるかに高速であることを確認します
tamersalama

5
問題は、完全なレコードが返されないことです
Used_By_Already

@ user2067753いいえ、完全なレコードを返しません。複数の列で同じMAX().. KEEP ..式を使用できるため、必要なすべての列を選択できます。ただし、多数の列が必要で、SELECT *を使用したい場合は不便です。
デイブ・コスタ

51

正確な列名はわかりませんが、次のようになります。

    ユーザーID、値を選択
      ユーザーu1から
     where date =(select max(date)
                     ユーザーu2から
                    ここで、u1.userid = u2.userid)

3
おそらくそれほど効率的ではない、スティーブ。
David Aldridge

7
Oracleクエリオプティマイザを過小評価している可能性があります。
ラファウDowgird

3
どういたしまして。これはほぼ確実に、日付を取得するためのネストされたループ結合によるフルスキャンとして実装されます。あなたはテーブルの行数の4倍のオーダーの論理ioについて話しているので、重要な量のデータには恐ろしいです。
David Aldridge

4
参考までに、「効率的ではないがうまくいく」は「うまくいくが効率的ではない」と同じです。設計目標としての効率をあきらめたのはいつですか?
David Aldridge

6
+1は、データテーブルの長さが数百万行でない場合に最もわかりやすいソリューションです。コードを変更するすべてのスキルレベルの複数の開発者がいる場合、理解しやすさが重要であり、1秒未満のパフォーマンスでは気付かないほどです。
n00b 2013

35

仕事をしていないので、手元にOracleはありませんが、OracleではIN句で複数の列を照合できるため、少なくとも相関サブクエリを使用するオプションを回避する必要があることを思い出しているようです。考え。

次のようなものかもしれません(列リストを括弧で囲む必要があるかどうか覚えていません):

SELECT * 
FROM MyTable
WHERE (User, Date) IN
  ( SELECT User, MAX(Date) FROM MyTable GROUP BY User)

編集:実際に試してみました:

SQL> create table MyTable (usr char(1), dt date);
SQL> insert into mytable values ('A','01-JAN-2009');
SQL> insert into mytable values ('B','01-JAN-2009');
SQL> insert into mytable values ('A', '31-DEC-2008');
SQL> insert into mytable values ('B', '31-DEC-2008');
SQL> select usr, dt from mytable
  2  where (usr, dt) in 
  3  ( select usr, max(dt) from mytable group by usr)
  4  /

U DT
- ---------
A 01-JAN-09
B 01-JAN-09

そのため、他の場所で言及された新しいおかしなもののいくつかはよりパフォーマンスが高いかもしれませんが、それは機能します。


4
これはPostgreSQLでもうまく動作します。そして、私はそれの単純さと一般性が好きです-サブクエリは「ここが私の基準です」と言い、外側のクエリは「そしてここに私が見たい詳細があります」と言っています。+1。
j_random_hacker

13

あなたがOracleを要求したのは知っていますが、SQL 2005ではこれを使用します。


-- Single Value
;WITH ByDate
AS (
SELECT UserId, Value, ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Date DESC) RowNum
FROM UserDates
)
SELECT UserId, Value
FROM ByDate
WHERE RowNum = 1

-- Multiple values where dates match
;WITH ByDate
AS (
SELECT UserId, Value, RANK() OVER (PARTITION BY UserId ORDER BY Date DESC) Rnk
FROM UserDates
)
SELECT UserId, Value
FROM ByDate
WHERE Rnk = 1

7

テストするOracleはありませんが、最も効率的なソリューションは分析クエリを使用することです。次のようになります。

SELECT DISTINCT
    UserId
  , MaxValue
FROM (
    SELECT UserId
      , FIRST (Value) Over (
          PARTITION BY UserId
          ORDER BY Date DESC
        ) MaxValue
    FROM SomeTable
  )

私はあなたが外側のクエリを取り除き、内側に区別を付けることができると思いますが、私にはわかりません。その間、私はこれが機能することを知っています。

分析クエリについて知りたい場合は、 http: //www.orafaq.com/node/55およびhttp://www.akadia.com/services/ora_analytic_functions.htmlをます。ここに短い要約があります。

分析クエリでは、データセット全体を並べ替えてから、順次処理します。それを処理するときに、特定の基準に従ってデータセットを分割し、各行についてウィンドウを確認し(デフォルトは現在の行への分割の最初の値です-このデフォルトも最も効率的です)、分析関数の数(そのリストは集計関数と非常に似ています)。

この場合、内部クエリは次のようになります。データセット全体は、UserId、次にDate DESCでソートされます。その後、1つのパスで処理します。各行について、UserIdとそのUserIdで最初に確認された日付を返します(日付がDESCでソートされているため、これが最大日付です)。これにより、重複した行で答えが得られます。次に、外側のDISTINCTが重複を押しつぶします。

これは、分析クエリの特に素晴らしい例ではありません。はるかに大きな勝利を収めるには、財務領収書の表を取り、各ユーザーと領収書について、彼らが支払った金額の現在の合計を計算することを検討してください。分析クエリはそれを効率的に解決します。他のソリューションは効率が良くありません。これが2003 SQL標準の一部である理由です。(残念ながらPostgresにはまだありません。Grrr...)


質問に完全に回答するには、日付の値を返す必要もあります。それが別のfirst_value句を意味する場合、ソリューションは本来あるべきものよりも複雑であり、max(date)に基づく分析メソッドがより適切に読み取れることをお勧めします。
David Aldridge

質問文は日付を返すことについては何も述べていません。これを行うには、別のFIRST(Date)を追加するか、日付をクエリして外部クエリをGROUP BYに変更します。私は最初のものを使用し、オプティマイザが両方を1つのパスで計算することを期待します。
user11318 '09 / 09/23

「質問文は日付を返すことについて何も言っていない」...はい、そうです。ごめんなさい。しかし、FIRST_VALUE句をさらに追加すると、すぐに面倒になります。これは単一のウィンドウの並べ替えですが、その行に対して返す列が20列ある場合は、大量のコードを記述していました。
デビッドアルドリッジ

また、この解決策は、単一のユーザーIDに最大日付と異なるVALUEを持つ複数の行があるデータに対しては非決定的であると思います。答えよりも質問の方が欠点です。
David Aldridge

1
私はそれが痛々しく冗長であることに同意します。しかし、SQLは一般的にそうではありませんか?そして、あなたはその解決策が非決定的であるということは正しいです。絆に対処するには複数の方法があり、時にはそれぞれがあなたの望むものです。
user11318 2008

6

QUALIFY句は最も単純であり、最良でもありませんか?

select userid, my_date, ...
from users
qualify rank() over (partition by userid order by my_date desc) = 1

コンテキストについては、ここのTeradataでは、この適度なサイズテストが、このQUALIFYバージョンで17秒、「インラインビュー」/ Aldridgeソリューション#1で23秒で実行されています。


1
これは私の意見では最良の答えです。ただし、rank()つながりがある場合は注意してください。最終的には複数になる可能性がありrank=1ます。row_number()本当に1つのレコードだけが返されるようにしたい場合は、使用した方がよいでしょう。
cartbeforehorse

1
また、このQUALIFY条項はTeradataに固有のものであることに注意してください。Oracleでは(少なくとも)クエリをネストWHEREし、ラッピングselectステートメントの句を使用してフィルター処理する必要があります(おそらく、パフォーマンスに少し影響があると思います)。
cartbeforehorse

5

ではOracle 12c+上位nクエリと分析関数rankを使用して、サブクエリなしで非常に簡潔にこれを実現できます。

select *
from your_table
order by rank() over (partition by user_id order by my_date desc)
fetch first 1 row with ties;

上記は、ユーザーごとに最大my_dateを持つすべての行を返します。

あなたが最大の日付を持つ唯一の1行をしたい場合は、交換するrankrow_number

select *
from your_table
order by row_number() over (partition by user_id order by my_date desc)
fetch first 1 row with ties; 

5

を使用ROW_NUMBER()してDate、各の降順で一意のランキングを割り当て、それぞれUserIdの最初の行にフィルターをかけますUserId(つまり、ROW_NUMBER= 1)。

SELECT UserId, Value, Date
FROM (SELECT UserId, Value, Date,
        ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Date DESC) rn
      FROM users) u
WHERE rn = 1;

5

PostgreSQL 8.4以降では、これを使用できます。

select user_id, user_value_1, user_value_2
  from (select user_id, user_value_1, user_value_2, row_number()
          over (partition by user_id order by user_date desc) 
        from users) as r
  where r.row_number=1

3

私はあなたがこれまでのクエリに対してこのバリアントを作成したものです:

SELECT UserId, Value FROM Users U1 WHERE 
Date = ( SELECT MAX(Date)    FROM Users where UserId = U1.UserId)

3
Select  
   UserID,  
   Value,  
   Date  
From  
   Table,  
   (  
      Select  
          UserID,  
          Max(Date) as MDate  
      From  
          Table  
      Group by  
          UserID  
    ) as subQuery  
Where  
   Table.UserID = subQuery.UserID and  
   Table.Date = subQuery.mDate  

3

仕事で「ライブ」の例を書く必要がありました:)

これは、同じ日付のUserIdの複数の値をサポートします。

列:UserId、Value、Date

SELECT
   DISTINCT UserId,
   MAX(Date) OVER (PARTITION BY UserId ORDER BY Date DESC),
   MAX(Values) OVER (PARTITION BY UserId ORDER BY Date DESC)
FROM
(
   SELECT UserId, Date, SUM(Value) As Values
   FROM <<table_name>>
   GROUP BY UserId, Date
)

MAXの代わりにFIRST_VALUEを使用して、Explain Planでルックアップできます。遊ぶ時間はありませんでした。

もちろん、巨大なテーブルを検索する場合は、クエリでFULLヒントを使用する方が良いでしょう。


3
select VALUE from TABLE1 where TIME = 
   (select max(TIME) from TABLE1 where DATE= 
   (select max(DATE) from TABLE1 where CRITERIA=CRITERIA))

2

このようなものだと思います。(構文の誤りを許してください。この時点でHQLを使用することに慣れています!)

編集:質問も誤解してください!クエリを修正しました...

SELECT UserId, Value
FROM Users AS user
WHERE Date = (
    SELECT MAX(Date)
    FROM Users AS maxtest
    WHERE maxtest.UserId = user.UserId
)

"for each UserId"条件を満たしていません
David Aldridge

どこで失敗しますか?UsersのすべてのUserIDについて、そのUserIDを含む少なくとも1つの行が返されることが保証されます。または、どこかに特別なケースがありませんか?
jdmichal 2008

2

(T-SQL)最初にすべてのユーザーとその最大日付を取得します。テーブルと結合して、maxdatesのユーザーに対応する値を見つけます。

create table users (userid int , value int , date datetime)
insert into users values (1, 1, '20010101')
insert into users values (1, 2, '20020101')
insert into users values (2, 1, '20010101')
insert into users values (2, 3, '20030101')

select T1.userid, T1.value, T1.date 
    from users T1,
    (select max(date) as maxdate, userid from users group by userid) T2    
    where T1.userid= T2.userid and T1.date = T2.maxdate

結果:

userid      value       date                                    
----------- ----------- -------------------------- 
2           3           2003-01-01 00:00:00.000
1           2           2002-01-01 00:00:00.000

2

ここでの答えはOracleのみです。これは、すべてのSQLにおけるもう少し高度な回答です。

誰が全体の宿題の最高の結果(宿題ポイントの最大合計)を持っていますか?

SELECT FIRST, LAST, SUM(POINTS) AS TOTAL
FROM STUDENTS S, RESULTS R
WHERE S.SID = R.SID AND R.CAT = 'H'
GROUP BY S.SID, FIRST, LAST
HAVING SUM(POINTS) >= ALL (SELECT SUM (POINTS)
FROM RESULTS
WHERE CAT = 'H'
GROUP BY SID)

そして、いくつかの説明が必要な、もっと時間のかかる例を示します。

2008年に最も人気のある本(ISBNとタイトル)、つまり2008年に最も頻繁に借りられる本を提供します。

SELECT X.ISBN, X.title, X.loans
FROM (SELECT Book.ISBN, Book.title, count(Loan.dateTimeOut) AS loans
FROM CatalogEntry Book
LEFT JOIN BookOnShelf Copy
ON Book.bookId = Copy.bookId
LEFT JOIN (SELECT * FROM Loan WHERE YEAR(Loan.dateTimeOut) = 2008) Loan 
ON Copy.copyId = Loan.copyId
GROUP BY Book.title) X
HAVING loans >= ALL (SELECT count(Loan.dateTimeOut) AS loans
FROM CatalogEntry Book
LEFT JOIN BookOnShelf Copy
ON Book.bookId = Copy.bookId
LEFT JOIN (SELECT * FROM Loan WHERE YEAR(Loan.dateTimeOut) = 2008) Loan 
ON Copy.copyId = Loan.copyId
GROUP BY Book.title);

これが(誰でも)役立つことを願っています.. :)

よろしく、Guus


受け入れられた答えは「Oracleのみ」ではありません-標準SQL(多くのDBMSでサポートされています)
a_horse_with_no_name

2

日付が特定のユーザーIDに対して一意であると仮定して、以下にいくつかのTSQLを示します。

SELECT 
    UserTest.UserID, UserTest.Value
FROM UserTest
INNER JOIN
(
    SELECT UserID, MAX(Date) MaxDate
    FROM UserTest
    GROUP BY UserID
) Dates
ON UserTest.UserID = Dates.UserID
AND UserTest.Date = Dates.MaxDate 

2

私はパーティーにかなり遅れましたが、次のハックは相関サブクエリとすべての分析関数の両方を上回りますが、制限が1つあります。値を文字列に変換する必要があります。したがって、日付、数値、その他の文字列に対して機能します。コードは良く見えませんが、実行プロファイルは素晴らしいです。

select
    userid,
    to_number(substr(max(to_char(date,'yyyymmdd') || to_char(value)), 9)) as value,
    max(date) as date
from 
    users
group by
    userid

このコードがうまく機能する理由は、テーブルを1回スキャンするだけでよいためです。インデックスを必要とせず、最も重要なのは、ほとんどの分析機能が行うように、テーブルをソートする必要がないことです。ただし、単一のユーザーIDの結果をフィルタリングする必要がある場合は、インデックスが役立ちます。


ほとんどのプランと比べて優れた実行計画ですが、これらすべてのトリックをいくつかのフィールドに適用するのは面倒で、逆効果になる可能性があります。しかし、非常に興味深い-ありがとう。sqlfiddle.com/#!4/2749b5/23を
Used_By_Already

これは退屈な作業になる可能性があります。そのため、クエリのパフォーマンスに必要な場合にのみこれを実行する必要があります。これは、ETLスクリプトの場合によく見られます。
aLevelOfIndirection 14

これはすごく素敵。LISTAGGを使用して同様のことを行いましたが、見た目は醜いです。postgresには、array_aggを使用したより良い代替案があります。私の答えを見てください:)
Bruno Calza

1
select userid, value, date
  from thetable t1 ,
       ( select t2.userid, max(t2.date) date2 
           from thetable t2 
          group by t2.userid ) t3
 where t3.userid t1.userid and
       t3.date2 = t1.date

私はこれが機能します。HTH


1

これはうまくいくと思いますか?

Select
T1.UserId,
(Select Top 1 T2.Value From Table T2 Where T2.UserId = T1.UserId Order By Date Desc) As 'Value'
From
Table T1
Group By
T1.UserId
Order By
T1.UserId

1

最初に私が質問を読み間違えて、上の答えに続いて、正しい結果の完全な例を示します。

CREATE TABLE table_name (id int, the_value varchar(2), the_date datetime);

INSERT INTO table_name (id,the_value,the_date) VALUES(1 ,'a','1/1/2000');
INSERT INTO table_name (id,the_value,the_date) VALUES(1 ,'b','2/2/2002');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'c','1/1/2000');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'d','3/3/2003');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'e','3/3/2003');

-

  select id, the_value
      from table_name u1
      where the_date = (select max(the_date)
                     from table_name u2
                     where u1.id = u2.id)

-

id          the_value
----------- ---------
2           d
2           e
1           b

(3 row(s) affected)

1

これは重複も処理します(user_idごとに1行を返します):

SELECT *
FROM (
  SELECT u.*, FIRST_VALUE(u.rowid) OVER(PARTITION BY u.user_id ORDER BY u.date DESC) AS last_rowid
  FROM users u
) u2
WHERE u2.rowid = u2.last_rowid

1

これをテストしただけで、ログテーブルで機能するようです

select ColumnNames, max(DateColumn) from log  group by ColumnNames order by 1 desc

1

これは次のように単純でなければなりません。

SELECT UserId, Value
FROM Users u
WHERE Date = (SELECT MAX(Date) FROM Users WHERE UserID = u.UserID)

1

パーティションKEEP、DENSE_RANKの概念を持たないMySQLのソリューション。

select userid,
       my_date,
       ...
from
(
select @sno:= case when @pid<>userid then 0
                    else @sno+1
    end as serialnumber, 
    @pid:=userid,
       my_Date,
       ...
from   users order by userid, my_date
) a
where a.serialnumber=0

リファレンス:http : //benincampus.blogspot.com/2013/08/select-rows-which-have-maxmin-value-in.html


これは「他のDBでも」機能しません。これはMySQLとSQL Serverでのみ機能します。これは、同様の変数の概念があるためです。Oracle、Postgres、DB2、Derby、H2、HSQLDB、Vertica、Greenplumでは動作しません。さらに、受け入れられた答えは標準のANSI SQLです(これは、MySQLだけがサポートしていないことを知っています)
a_horse_with_no_name

馬、私はあなたが正しいと思います。他のDBやANSIに関する知識がありません。私のソリューションは、標準の方法でANSI SQLを解決するための適切なサポートを持たないMySQLの問題を解決できます。
Ben Lin

1

Postgresを使用してarray_aggいる場合は、次のように使用できます

SELECT userid,MAX(adate),(array_agg(value ORDER BY adate DESC))[1] as value
FROM YOURTABLE
GROUP BY userid

私はOracleに慣れていません。これは私が思いついたものです

SELECT 
  userid,
  MAX(adate),
  SUBSTR(
    (LISTAGG(value, ',') WITHIN GROUP (ORDER BY adate DESC)),
    0,
    INSTR((LISTAGG(value, ',') WITHIN GROUP (ORDER BY adate DESC)), ',')-1
  ) as value 
FROM YOURTABLE
GROUP BY userid 

どちらのクエリも、受け入れられた回答と同じ結果を返します。SQLFiddlesを参照してください。

  1. 受け入れられた答え
  2. Postgresによる私の解決策
  3. Oracleによる私のソリューション

0

(UserID、Date)が一意である場合、つまり同じユーザーに対して2度日付が表示されない場合:

select TheTable.UserID, TheTable.Value
from TheTable inner join (select UserID, max([Date]) MaxDate
                          from TheTable
                          group by UserID) UserMaxDate
     on TheTable.UserID = UserMaxDate.UserID
        TheTable.[Date] = UserMaxDate.MaxDate;

UserIDでも参加する必要があると思います
Tom H

0
select   UserId,max(Date) over (partition by UserId) value from users;

2
これにより、ユーザーごとに1行だけでなく、すべての行が返されます。
Jon Heller、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.