0

特定のルックアップを実行するクエリを作成するのに少し迷っています。クエリの最初の部分を実行すると、アカウントの一部のエントリが欠落しているすべてのアカウントが返されます。次に、最後のログイン試行に基づいて、このサブセットをさらにフィルタリングする必要があります。

テーブル構造は次のとおりです。

  • users テーブルには、すべてのユーザー情報が含まれています。project_id 33 の下のユーザーのみを考慮します。
  • users_account_list には、ユーザーが持っているすべてのアカウントが含まれます。サービス 50 のエントリを持っていないユーザーのみを考慮します。
  • users_login_logs には、ユーザーのすべてのログイン試行が含まれます。

私はこれを持っている元のクエリ:

SELECT u.id,
       u.login, 
       u.email, 
       u.nickname,
       b.station_login AS "additionals.station_login",
       a.id AS "user_account_list.id",
       a.game_id AS "user_account_list.game_id",
       a.game_uid AS "user_account_list.game_uid",
       c.created_at AS "last login"
FROM users u
LEFT JOIN user_account_list a ON u.id = a.user_id AND a.game_id = 50
LEFT JOIN user_additionals b ON u.id = b.id
LEFT JOIN user_login_logs c ON u.id = c.user_id
WHERE u.project_id = 33
AND u.verified_at IS NOT NULL
AND (a.id IS NULL OR a.game_id IS NULL OR a.game_uid IS NULL)
AND (b.station_login IS NULL OR b.station_login = '')
ORDER BY c.created_at DESC

これにより、project_id 33 で登録され、game_id 50 のエントリがなく、追加情報テーブルに情報が保存されていないすべてのユーザーが返されます。オプションですが、関係ありません。返されるデータを制限するだけです。ユーザーごとに複数の行が返され、最新のログイン日に従ってソートされます。

私が必要とするのは、最新のログイン日で返されるユーザーごとに 1 行だけを取得することです。ORDER BY を GROUP by u.id に置き換えてみましたが、これにより最新ではなく最も古い結果が返されます。

どうやって:

  • 返される行をユーザーごとに 1 行に制限する
  • 行がユーザーの最新のログイン試行に基づいていることを確認してください。

編集

これは現在、クエリが返すものです:

+----+-------+-----------------+----------+---------------------------+----------------------+---------------------------+----------------------------+---------------------+
| id | login | email           | nickname | additionals.station_login | user_account_list.id | user_account_list.game_id | user_account_list.game_uid | last login          |
+----+-------+-----------------+----------+---------------------------+----------------------+---------------------------+----------------------------+---------------------+
|  1 | usrnm | someon@mail.com | Nickname |                           |                 NULL |                      NULL | NULL                       | 2012-10-19 00:00:00 |
|  1 | usrnm | someon@mail.com | Nickname |                           |                 NULL |                      NULL | NULL                       | 2012-10-18 00:00:00 |
|  1 | usrnm | someon@mail.com | Nickname |                           |                 NULL |                      NULL | NULL                       | 2012-10-17 00:00:00 |
+----+-------+-----------------+----------+---------------------------+----------------------+---------------------------+----------------------------+---------------------+
3 rows in set (0.08 sec)
4

2 に答える 2

3

これを行う1つの方法は、次JOINのテーブルを使用してテーブルを作成することです。user_login_logs

   SELECT user_id, MAX(created_at) LatestDate
   FROM user_login_logs 
   GROUP BY user_id

に参加しcreated_at = LatestDateます。これにより、ユーザーのログインログが各ユーザーの最新の作成日に制限されます。これがあなたの質問です:

SELECT u.id,
       u.login, 
       u.email, 
       u.nickname,
       b.station_login AS "additionals.station_login",
       a.id AS "user_account_list.id",
       a.game_id AS "user_account_list.game_id",
       a.game_uid AS "user_account_list.game_uid",
       c.created_at AS "last login"
FROM users u
LEFT JOIN user_account_list a ON u.id = a.user_id AND a.game_id = 50
LEFT JOIN user_additionals b ON u.id = b.id
LEFT JOIN user_login_logs c ON u.id = c.user_id
LEFT JOIN
(
   SELECT user_id, MAX(created_at) LatestDate
   FROM user_login_logs 
   GROUP BY user_id
) maxc ON c.userid = maxc.userid AND c.created_at = maxc.LatestDate
WHERE u.project_id = 33
AND u.verified_at IS NOT NULL
AND (a.id IS NULL OR a.game_id IS NULL OR a.game_uid IS NULL)
AND (b.station_login IS NULL OR b.station_login = '')
ORDER BY c.created_at DESC;

注:あなたはLEFT JOINテーブルであるため、左側の結合されたテーブルの一致しない行が結果セットに含まれます。それらを結果セットに含める必要がない場合は、INNER JOIN代わりに使用してください。

于 2012-12-06T11:33:14.403 に答える
2

試したようORDER BYに aに置き換える必要がありますが、SELECT でグループの最後の日付が必要であることを示す必要があるため、置き換える必要がありますGROUP by u.id

c.created_at AS "last login"

MAX(c.created_at) AS "last login"

のおかげで、これはユーザーごとに1行のみを返しGROUP BY、各ユーザーの最新の日付のみを選択しますMAX()

編集:間違いを避けるために、エイリアス列名にスペースを含むものを使用しないようにする必要があると思います

于 2012-12-06T11:28:40.977 に答える