нужна помощь в создании запроса SELECT для выбора уникальных строк - PullRequest
1 голос
/ 26 июля 2011

Я хочу создать SQL-запрос для SQLite3 DB .

В моей таблице приведены следующие данные образца

7/1/2011   8:02   LOGIN   JOE
7/1/2011   8:15   LOGIN   CAROL
7/1/2011   8:15   LOGIN   JOE
7/1/2011   8:35   LOGIN   SANDY
7/1/2011   13:15  LOGOFF  SANDY
7/1/2011   16:15  LOGIN   SANDY
7/1/2011   18:12  LOGOFF  CAROL
7/1/2011   21:09  LOGOFF  TED
7/1/2011   21:19  LOGIN   TED
7/1/2011   22:10  LOGOFF  JOE
7/1/2011   23:40  LOGOFF  SANDY
7/2/2011   9:00   LOGIN   JOE
7/3/2011   10:00  LOGIN   JOE
7/3/2011   20:00  LOGOFF  SANDY

в основном я хочу получить только первую запись LOGIN для каждой даты и последнюю запись LOGOFF для той же даты (если доступно)

Итак, я хочу, чтобы запрос выдал

7/1/2011   8:02   LOGIN   JOE
7/1/2011   8:15   LOGIN   CAROL
7/1/2011   8:35   LOGIN   SANDY
7/1/2011   18:12  LOGOFF  CAROL
7/1/2011   21:09  LOGOFF  TED
7/1/2011   21:19  LOGIN   TED
7/1/2011   22:10  LOGOFF  JOE
7/1/2011   23:40  LOGOFF  SANDY
7/2/2011   9:00   LOGIN   JOE
7/3/2011   10:00  LOGIN   JOE
7/3/2011   20:00  LOGOFF  SANDY

Как видите, нас интересует первый вход в систему и последний выход для пользователя.

Все поля являются отдельными полями, которые хранятся как VARCHAR () ИСКЛЮЧИТЬ ДАТУ И ВРЕМЯ Дата сохраняется как ДАТА Время сохраняется как ВРЕМЯ Ниже приведены имена полей и то, что они представляют.

tddate - date
tdtime - time
tdtype - LOGIN/LOGOFF
tdusername - username

Не все входы в систему имеют соответствующий выход из системы, потому что человек может отключиться от сети без фактического выхода из системы.

Вот запрос, который я пытался использовать

select tddate,
        case tdtype
                   when 'LOGIN' then Min(tdtime)          
                   when 'LOGOFF' then Max(tdtime)        
                   end as tdtype  from TimeData                     
WHERE tdusername LIKE "JOE"

я получаю 0 строк данных

Ответы [ 3 ]

2 голосов
/ 26 июля 2011

То, что у вас есть, работает почти так, как вы хотите. Вам просто нужно добавить группу по предложению:

SELECT
    tddate,
    CASE tdtype
        WHEN 'LOGIN' THEN MIN(tdtime)
        WHEN 'LOGOFF' THEN MAX(tdtime)
        ELSE NULL
    END AS tdtime,
    tdtype,
    tdusername
FROM TimeData
GROUP BY tddate, tdtype, tdusername
ORDER BY tddate, tdtime
0 голосов
/ 26 июля 2011
select tddate, max(tdtime) time, tdtype, tdusername 
from table 
where tdtype = 'LOGIN' 
group by tddate, tdtype, tdusername

union

select tddate, min(tdtime) time, tdtype, tdusername 
from table 
where tdtype = 'LOGOUT' 
group by tddate, tdtype, tdusername
0 голосов
/ 26 июля 2011

Вам понадобится либо самостоятельное присоединение, либо объединение, а также разделение результатов, чтобы эта работа работала:

   SELECT * FROM (
SELECT DateField
        , TimeField
        , ActionField
        , UserField
        , RealDate = Max(CAST(DateField + ' ' + TimeField AS DateTime))
        , RowNum = ROW_NUMBER() OVER (PARTITION BY UserField, ActionField ORDER BY Cast(DateField + ' ' + TimeField AS DateTime) DESC)
FROM   theTable
WHERE  ActionField='LOGOFF'
GROUP BY Datefield, TimeField, ActionField, UserField
UNION
SELECT DateField
        , TimeField
        , ActionField
        , UserField
        , RealDate = Max(Cast(DateField + ' ' + TimeField AS DateTime))
        , RowNum = ROW_NUMBER() OVER (PARTITION BY UserField, ActionField ORDER BY Cast(DateField + ' ' + TimeField AS DateTime) DESC)
FROM   theTable
WHERE  ActionField='LOGIN'
GROUP BY Datefield, TimeField, ActionField, UserField) AS Result
WHERE Result.RowNum = 1
ORDER BY UserField, RealDate

РЕДАКТИРОВАТЬ: Неважно - я не понимал, что это был SQLite. Там нет функции row_number там. Вам могут понадобиться временные таблицы ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...