2012-01-17 22 views
1

私は2つのテーブルUsersVisitorsを持っています。 Usersでは、私はすべてのユーザー情報を持っており、Visitorsにログイン結果を載せています。ユーザーがログインするたびに、新しいレコードがuser_iddatetimeVisitorsに入ります。LEFT JOIN、GROUP BY、ORDER BYのMySQLクエリ

ユーザーを最後にログインした日時で選択します。これどうやってするの?

答えて

1

例えば選択

でサブクエリを使用してみてください:select u.name,(select datetime from visitors v where u.id_user = v.id_user order by datetime desc limit 1) as lastlogin_datetme from users u;

+0

おかげで、私はそれが働いて得るdidntの。私はすべてのフィールドを編集しましたが、エラーが発生します。これは私が試したものです:SELECT u.users_id、u.users_firstname、u.users_lastname、u.users_company、u.users_email \t(訪問者からのdatetime時間v u.users_id = v.user_id order at datetime desc limit 1)as lastlogin_datetimeはユーザーuからのものです。これはエラーです。#1064 - SQL構文にエラーがあります。あなたのMySQLサーバのバージョンに対応するマニュアルをチェックして、正しい構文を使用して、近くの「訪問者のSELECT datetime」v.u.users_id = vの近くで使用するようにしてください。user_id order by datetime d '2行目 –

+0

-1これはスケーラブルなクエリではありません。1Mのユーザがいれば1Mサブクエリになります。それを正しく行う方法は私の答えを見てください。 – Bohemian

+0

probaly問題はmysqlの制限です。 "limit 1"、 "limit 0,1"の代わりに試してください –

2

(効果的nユーザーのためnのクエリを実行している意味します)、すべてのユーザーのための最も最近の時間を計算するのにサブクエリを使用しないようにするには、使用

select u.*, last_login 
from users u 
left join (select id, last_login 
    from (select u.id, v.last_login 
    from users u 
    join visits v on v.user_id = u.id 
    order by 1, 2 desc 
) x 
group by 1) y on y.id = u.id; 
:各グループの 最初行を返す凝集することなく group by のMySQLの「トリック」、

このクエリは非常にうまくいくので、各ユーザーのサブクエリはありません。ここで

は何が起こっているのブレークダウンです:

  • xとしてエイリアス)最も内側のクエリは、我々は、各ユーザID
  • 最初をしたいLAST_VISIT値を持つためには、ユーザIDとLAST_VISITを取得します
  • 次のクエリ(yのエイリアス)は、ユーザーID group byを使用して、を使用して集計関数を使用します。他のデータベースではこれはエラーですが、mysqlを使用すると、の最初のの行がすべて返されます。つまり、最後に指定したlast_visitの値です。
  • 最終的な最も外側のクエリはleft joinこれらの結果を、そうでない場合、我々はあなたが後で行が存在することはできないと述べているwhere句では、ユーザ行
+1

+1すてきなクエリ!素晴らしい説明! –

+0

動作しません:テーブル訪問者は訪問者である必要があります。少なくともOPに基づいています。しかし、コンセプトは固い – xQbert

+0

あなたの助けに感謝しますが、私はそれを働かせませんでした。エイリアスyの前に、テーブル訪問者を置く必要がありますか? uが参加左 ユーザーからの日時 、* Uを選択します(user_idを選択し、ユーザーからのv.datetime 、u.users_id選択(から日時 uは、訪問者がv.user_id = u.users_id にV加入 :私はこれを試してみました1、2 desc desc )x group by 1)y.user_id = u.users_idの訪問者y;これはエラーです:#1064 - SQL構文にエラーがあります。あなたのMySQLサーバのバージョンに対応するマニュアルをチェックして、正しい構文が 'y on y.user_id = u.users_id LIMIT 0,30'の9行目近くで使用するようにしてください –

0
SELECT cur.textID, cur.fromEmail, cur.subject, 
    cur.timestamp, cur.read 
FROM incomingEmails cur 
LEFT JOIN incomingEmails next 
    on cur.fromEmail = next.fromEmail 
    and cur.timestamp < next.timestamp 
WHERE next.timestamp is null 
and cur.toUserID = '$userID' 
ORDER BY LOWER(cur.fromEmail) 

Basically, you join the table on itself, searching for later rows. 

に参加したいLAST_VISITを与え、訪れたことのないユーザーのためのnull値を与えます。これにより、最新の行のみが表示されます。

タイムスタンプが同じ複数のメールがある場合は、 このクエリは精緻化が必要です。電子メールテーブルの増分ID列がある場合、同じようJOINを変更 :

LEFT JOIN incomingEmails next 
    on cur.fromEmail = next.fromEmail 
    and cur.id < next.id