在特定的

时间:2015-05-05 07:24:13

标签: mysql sql subquery left-join

users有三列:id, name, pass

另一个表loginsuser_id列,isright布尔(tinyint)列,表示登录是否成功以及date列。

我需要一个简单的left join来获取用户的姓名和密码(1),最后一次登录日期时间(成功与否)(2) 以及自上次成功登录后特定用户的登录次数(3)

(1)和(2)我可以实现

SELECT name, pass, MAX(date)
FROM users
LEFT JOIN logins ON logins.id = users.id
-- here either "GROUP BY users.id" or "WHERE users.id = 1234"

但是(3)似乎更难。我用Google搜索并发现了许多类似的问题,但没有一个问题确切地说明在特定条件成立后如何计算行数。 (它更复杂 - 计算用户的登录,而非每个人)

我甚至不知道如何在单独的查询中执行此操作(我更喜欢对3件事情进行一次查询,我想我必须使用子查询,尽管我更喜欢连接)。

SQL摆弄表和一些数据:http://sqlfiddle.com/#!9/a932b

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

直接的方法是有两个派生表:一个用于获取每个用户的最后一个登录日期,另一个用于获取每个用户的最后一个成功登录日期。然后从用户中选择,外部连接两个派生表并查看上次登录是否成功并在上次成功登录后计算(失败)登录。 (使用另一个DBMS,您更愿意使用MySQL缺少的分析函数。)

select 
  users.name, 
  users.pass, 
  (
    select max(isright)
    from logins 
    where user_id = students.id and date = last_login.date
  ) as last_login_successful,
  (
    select count(*)
    from logins
    where user_id = students.id and date > last_successful_login.date
  ) as last_logins_failed
from users
left outer join
(
  select user_id, max(date) as date
  from logins
  group by user_id
) last_login on last_login.user_id = users.id
left outer join
(
  select user_id, max(date) as date
  from logins
  where isright = 1
  group by user_id
) last_successful_login on last_successful_login.user_id = users.id;

这为每位用户提供了四种可能性:

  1. 用户从未尝试过登录。 last_login_successful为null,last_logins_failed无意义。
  2. 用户的登录全部失败。 last_login_successful为0,last_logins_failed无意义。
  3. 用户上次登录成功。 last_login_successful为1,last_logins_failed无意义。
  4. 用户成功登录一次,但至少上次尝试时失败了。 last_login_successful为0,last_logins_failed是上次成功登录后的失败次数。
  5. 这是一个小提琴:http://sqlfiddle.com/#!9/57b7d/1

    编辑:还要在用户从未登录时计算失败的登录次数:如果用户从未登录,则其last_login.date为空。在last_logins_failed中,您希望计算上次登录之前从不的所有记录:

      (
        select count(*)
        from logins
        where user_id = students.id and (date > last_successful_login.date
        or last_successful_login.date is null)
      ) as last_logins_failed
    

答案 1 :(得分:0)

如何使用仅具有以下查询的最新登录详细信息的视图

select l.user_id, l.date, l.isright from logins l
where l.date >= (select max(l2.date) from logins l2
    where l2.isright=1 and l2.user_id = l.user_id)