如何在SQL中按日期和名称分组

时间:2012-03-26 14:50:20

标签: mysql sql sql-order-by

实际上我想要的是非常简单,我希望每天从用户那里获得第一次登录和最后一次注销。为了得到它我有一个数据库,我可以创建SQLQueries但我无法得到我想要的结果。 我将用这个例子来解释它:

 (NAME-LOGIN-LOGOUT)
| AAAAAAAAAAAA       | 23/02/2012 10:33:56,323 | 23/02/2012 16:03:10,323
| AAAAAAAAAAAA       | 24/02/2012 07:59:55,787 | 24/02/2012 13:32:16,787
| AAAAAAAAAAAA       | 24/02/2012 13:34:15,823 | 24/02/2012 15:00:54,823
| AAAAAAAAAAAA       | 27/02/2012 08:00:24,283 | 27/02/2012 16:00:14,283
| AAAAAAAAAAAA       | 28/02/2012 07:56:26,78  | 28/02/2012 13:09:16,78
| AAAAAAAAAAAA       | 28/02/2012 13:09:58,287 | 28/02/2012 15:09:08,287
| AAAAAAAAAAAA       | 29/02/2012 07:52:47,82  | 29/02/2012 16:03:37,82
| AAAAAAAAAAAA       | 22/02/2012 10:15:25,817 | 22/02/2012 10:24:42,817
| BBBBBBBBBBBB       | 20/02/2012 07:22:50,31  | 24/02/2012 14:16:43,31
| CCCCCCCCCCCC       | 15/02/2012 07:58:33,777 | 15/02/2012 16:02:53,777
| CCCCCCCCCCCC       | 16/02/2012 08:00:56,29  | 16/02/2012 15:03:06,29
| CCCCCCCCCCCC       | 17/02/2012 07:57:31,29  | 17/02/2012 16:00:34,29
| CCCCCCCCCCCC       | 20/02/2012 08:01:01,82  | 20/02/2012 15:00:09,82
| CCCCCCCCCCCC       | 21/02/2012 07:59:57,29  | 21/02/2012 14:40:13,29

我想要使用具有groupby属性的SQL sentece得到的结果(例如用户A):

(结果应该只显示第一次登录和当天的最后一次登出)

USER
{
    DATE
    {
      min(Login);
      max(LogOut);
    }
}



(NAME-LOGIN-LOGOUT)
AAAAAAAAAAAAA  23/02/2012 10:33:56,323   23/02/2012 16:03:10,323
AAAAAAAAAAAAA  24/02/2012 07:59:55,787   24/02/2012 15:00:54,823
AAAAAAAAAAAAA  27/02/2012 08:00:24,283   27/02/2012 16:00:14,283
AAAAAAAAAAAAA  28/02/2012 07:56:26,78    28/02/2012 15:09:08,287
.....

我想这是使用几个选择或条件,但我无法让它工作。 我真的很感激任何帮助。


我想出了以下答案,但是当我制作小组时,我仍然得到最后一行的最小值和最大值。似乎是首先获得Group,然后获得max和min值。我想成为另一种方式:),首先考虑日期和用户的最大值和分钟,然后按用户和日期分组。

SELECT EnterpriseName, LoginDate, LogOutDate, min(LoginTime), max(LogOutTime)
FROM
ipcc_table
WHERE LoginDate=LogOutDate
GROUP BY  EnterpriseName,LoginDate;

最好的问候

7 个答案:

答案 0 :(得分:3)

  

我希望每天从特定用户首次登录和退出。

SELECT name
      ,date(login) AS day
      ,min(login)  AS login
      ,min(logout) AS logout
FROM   tbl
WHERE  name = <my_name>
GROUP  BY name, date(login)
ORDER  BY name, date(login);

date() function应该是最合适的工具。

这没有考虑到第一次登出可能在第一次登录之前或多个会话可能交织在一起。但你的问题确实要求这个。


如果您确实希望每天从特定用户首次登录和随附的退出

SELECT i.name, i.day, i.login, o.logout
FROM  (
   SELECT name
         ,date(login) AS day
         ,min(login)  AS login
   FROM   tbl
   WHERE  name = <my_name>
   GROUP  BY name, date(login)
   )   i
JOIN   tbl o USING (name, login)
ORDER  BY i.name, i.login;

这假定(name, login)是唯一的。如果不是,你真的应该添加一个代理主键,比如自动增量列。

答案 1 :(得分:1)

你会做类似

的事情
select name, min(login), min(logout), trunc(login)
group by name, trunc(login)

trunc可能是特定于oracle的,并且在一个日期中转换(除其他外)一个带有时间的日期。这样的东西也必须在你的RDBMS中可用。

答案 2 :(得分:0)

SELECT name, DATE_FORMAT(login, '%d/%m/%Y') AS day, MIN(login) AS first_login, MAX(logout) AS last_logout
  FROM mytable
 GROUP BY name, day

我认为这是有效的MySQL语法,但我并不完全确定(我没有测试平台)。请注意,上次注销的日期可能与登录日期不同。

答案 3 :(得分:0)

QUOTE from OP:“我希望从特定用户获得第一个loginlogout每天”< / p>

SELECT `name`, MIN(`login`), MAX(`logout`) 
FROM table WHERE name = 'AAAA' GROUP BY YEAR(`login`), MONTH(`login`), DAY(`login`)

答案 4 :(得分:0)

试试这个:

SELECT * FROM table GROUP BY name ORDER BY login

然后你上次登录,如果你添加DESC,你首先登录。

答案 5 :(得分:0)

(假设DATE(login) < DATE(logout)时你想要发生什么):

    SELECT
        name
      , login
      , logout
    FROM
        tableX
    WHERE
        DATE(login) < DATE(logout)
  UNION ALL
    SELECT 
        name
      , MIN(login) 
      , MAX(logout) 
    FROM 
        tableX
    GROUP BY 
        name
      , DATE(login)
    HAVING 
        DATE(MIN(login)) = DATE(MAX(logout))

答案 6 :(得分:0)

当退出日期与登录日期不同时,应该发生什么事情并不完全清楚,所以我已经对这两种情况进行了补偿。

无论登录日期如何,您希望每天首次登录,以及任何一天的最后一次登出。

SELECT  Name,
        COALESCE(MIN(Login), EventDate) AS Login,
        COALESCE(MAX(LogOut), ADDTIME(EventDate, '23:59:59'))  AS LogOut
FROM    (   SELECT  Name,
                    DATE(Login) AS EventDate,
                    MIN(LogIn) AS Login,
                    NULL AS LogOut
            FROM    TestTable
            GROUP BY Name, DATE(Login)
            UNION
            SELECT  Name,
                    DATE(LogOut) AS EventDate,
                    NULL AS Login,
                    MAX(LogOut) AS LogOut
            FROM    TestTable
            GROUP BY Name, DATE(Login)
        ) AS d
GROUP BY Name, EventDate;

因此,对于上面的“BBBBBBBBBBBB”,这将返回

BBBBBBBBBBBB    2012-02-20 07:22:50  2012-02-20 23:59:59
BBBBBBBBBBBB    2012-02-24 00:00:00  2012-02-24 14:16:43

或者更简单的方法:

SELECT  Name,
        MIN(Login) AS Login,
        MAX(Logout) AS LogOut
FROM    TestTable
GROUP BY Name, DATE(Login)

上面的'BBBBBBBBBBBB'将返回

BBBBBBBBBBBB    2012-02-20 07:22:50   2012-02-24 14:16:43