Как сгруппировать по дате и имени в SQL - PullRequest
1 голос
/ 26 марта 2012

На самом деле то, что я хочу получить, довольно просто, я хочу получить первый вход в систему и последний выход из системы от пользователя в день. Для того, чтобы получить, что у меня есть база данных, где я могу сделать 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

Результат, который я хочу получить (например, для пользователя A), используя предложение SQL с атрибутом groupby:

(Результат должен отображать только первый вход в систему и последний выход в день)

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
.....

Я предполагаю, что используется несколько условий выбора или условия, но я не могу заставить его работать. Буду очень признателен за любую помощь.


Я придумал следующий ответ, но я все еще получаю значения mininum и maximun последней строки, когда делаю группу. Похоже, что сначала создается группа, а затем получают максимальные и минимальные значения. Я хотел бы быть наоборот :), сначала получите максимум и минимум с учетом даты и пользователя, а затем группируйте по пользователю и дате.

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

С наилучшими пожеланиями

Ответы [ 7 ]

3 голосов
/ 26 марта 2012

Я хочу получить первый вход и выход от определенного пользователя в день.

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() должна быть наиболееПодходящий инструмент здесь.

Это не учитывает, что первый выход из системы может быть до того, как первый вход в систему или несколько сеансов могут быть переплетены.Но ваш вопрос спрашивает об этом.


Если вы действительно хотите первый логин и сопровождающий выход от определенного пользователя, в день:

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 голос
/ 26 марта 2012

Вы бы сделали что-то вроде

select name, min(login), min(logout), trunc(login)
group by name, trunc(login)

trunc, вероятно, специфичен для оракула и превращает (среди прочего) дату со временем в просто дату. Нечто подобное должно быть доступно и в вашей РСУБД.

0 голосов
/ 26 марта 2012

Не совсем ясно, что должно произойти, когда дата выхода из системы отличается от даты входа в систему, поэтому я компенсировал оба сценария.

Где вы хотите первый вход в систему каждый день и последнийВыйти из любого дня, независимо от даты входа.

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)

, что для 'BBBBBBBBBBB' выше этого было бывозврат

BBBBBBBBBBBB    2012-02-20 07:22:50   2012-02-24 14:16:43
0 голосов
/ 26 марта 2012

(делая предположение о том, что вы хотите, когда 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))
0 голосов
/ 26 марта 2012

Попробуйте это:

SELECT * FROM table GROUP BY name ORDER BY login

Тогда вы получите последний логин, если вы добавите DESC, вы получите первый логин.

0 голосов
/ 26 марта 2012

QUOTE from OP: «Я хочу получить первые login и logout от определенного пользователя , в день »

SELECT `name`, MIN(`login`), MAX(`logout`) 
FROM table WHERE name = 'AAAA' GROUP BY YEAR(`login`), MONTH(`login`), DAY(`login`)
0 голосов
/ 26 марта 2012
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, но я не совсем уверен (у меня нет тестовой платформы). Обратите внимание, что дата последнего выхода из системы может отличаться от даты входа в систему.

...