2016-04-27 12 views
0

SQLを使用して最新の結果を取得しようとしています。私はここで最も受け入れ答えをコピーしSQLに最新の日付が見つかりました。なぜ「内部結合」が必要ですか

SQL query to get most recent row for each instance of a given key

:私は、リンク、ウェブサイトを検索し、「stackoverflowの」からこの古い記事を見つけました。

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 

私が理解していないことは、なぜ以下のように使用できないのですか(つまり、なぜこの場合は「内部結合」操作が必要ですか)ですか? (私は信じているのMySQLを除く)

Select username, ip, max(time_stamp) as time_stamp 
    From users 
    Group By username 
+3

(1)使用しているデータベースで質問にタグを付けてください。 (2)動作しません。ほとんどのデータベースでは、 'ip'が' GROUP BY 'に含まれていないので構文エラーを返します.SQLエンジンはどちらの値を選択するのかわかりません(MySQLは構文を受け入れますが、 )。 –

+1

一般的なGROUP BYルールの意味は次のとおりです。 GROUP BY句が指定されている場合、SELECTリストの各列参照は、グループ化列を特定するか、または集合関数の引数でなければなりません。 – jarlh

答えて

3

ほとんどのSQLの変異体は、あなたのSELECTリスト内の任意の非集計列はまたあなたのGROUP BYであることが必要です。そうでない場合は、複数のip値を持つ単一のusernameの場合、どちらの結果に表示する必要がありますか?この場合、ユーザー名とIPのペアは一意であることがわかりますが、SQLエンジンはそれを常に知っているとは限りません。特に複雑なクエリの場合はそうです。

ユーザー:

username  ip    timestamp 
--------  -------------- --------- 
bob   167.49.122.122 2016-01-05 
john   167.49.122.123 2016-02-02 
bob   167.49.122.124 2016-04-01 

をあなたが見ることを期待するどのような結果の例を明確にするために

? "ボブ"の場合

ボブ/ 167.49.122.122/2016-04-01にする必要がありますか?ボブ/ 167.49.122.124/2016-04-01?どちらも?

あなたは、「まあ、明らかに、最大の日付を持つ行全体が欲しい」と言うかもしれませんが、人間にとって直感的であっても、それは第2のSELECTでも明らかです。

+2

良い答え。あなたがusername/ipの組が一意であるという事実を知っているなら、 'GROUP BY username、ip'で簡単なクエリを使うことができます。それ以外の場合は、ipの正しい値を得るために、より複雑な方法の1つを使用する必要があります。 – jussius

3

あなたの構文は、SQL Server(またはおそらくMS Access、しかし私は楽観的です)を示唆しています。 ANSI標準のSQLでの典型的なアプローチは、row_number()を使用することです:

select u.* 
from (select u.*, 
      row_number() over (partition by username order by time_stamp desc) as seqnum 
     from users u 
    ) u 
where seqnum = 1; 

明示joinを必要としないだけでなく、他の方法は間違いなくあります。

関連する問題