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 行以及他们的最新登录日期。我尝试用 u.id 的 GROUP 替换 ORDER BY但这给了我最旧的结果,而不是最新的。

我怎样才能:

  • 将返回的行限制为每个用户仅 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

做到这一点的一种方法是使用下JOINuser_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 GROUP by u.id,但您还需要在 SELECT 中表明您想要组中的最后一个日期,因此您需要替换

c.created_at AS "last login"

经过

MAX(c.created_at) AS "last login"

这将仅返回每个用户一行,这要GROUP BY归功于MAX()

编辑:我认为您应该避免使用带有空格的别名列名以避免错误

于 2012-12-06T11:28:40.977 回答