SQL для получения двух столбцов - PullRequest
0 голосов
/ 29 июня 2011

У меня есть такие записи в базе данных Oracle 10g

`with t as (
   select 1234 emp_number, to_date('19-JAN-09 07.06.00 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN'  SPECIFIER from dual union all
   select 1234 emp_number, to_date('19-JAN-09 08:40:53 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual union all
   select 1234 emp_number, to_date('19-JAN-09 08:50:40 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN'  SPECIFIER from dual union all
   select 1234 emp_number, to_date('19-JAN-09 09:50:32 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual union all
   select 1234 emp_number, to_date('19-JAN-09 10:07:18 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN'  SPECIFIER from dual union all
   select 1234 emp_number, to_date('19-JAN-09 02:49:07 PM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual union all   
   select 1234 emp_number, to_date('22-JAN-09 10:42:50 PM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN' SPECIFIER from dual union all
   select 1234 emp_number, to_date('23-JAN-09 06:50:40 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual union all
   select 1234 emp_number, to_date('23-JAN-09 10:49:55 PM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN' SPECIFIER from dual union all
   select 1234 emp_number, to_date('24-JAN-09 05:22:19 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual union all
   select 1234 emp_number, to_date('24-JAN-09 05:30:46 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN' SPECIFIER from dual union all
   select 1234 emp_number, to_date('24-JAN-09 05:43:51 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual union all
   select 1234 emp_number, to_date('24-JAN-09 05:48:40 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN' SPECIFIER from dual union all
   select 1234 emp_number, to_date('24-JAN-09 05:50:52 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual union all
   select 1234 emp_number, to_date('24-JAN-09 06:03:02 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'IN' SPECIFIER from dual union all
   select 1234 emp_number, to_date('24-JAN-09 06:43:44 AM', 'dd-MON-yy hh.mi.ss AM') TIME_IN_OUT, 'OUT' SPECIFIER from dual
   )`

Если вы посмотрите на данные 22 января 2009 года, у нас IN_TIME 22 января 2009 года 22.4250 и следующего дня OUT_TIMEв 23-ЯНВ 09 сентября 06.50.40 и снова в тот же день IN_TIME в 23-ЯНВ 09 09.49.55 PM и OUT_TIME в 24-JAN-09 05:22:19 AM.Таким образом, в идеале вывод должен быть

EMP_NUMBER DAY                TIME_IN                                           TIME_OUT
`
1234         19/Jun/11          19-JAN-09 10.07.18 AM               19-JAN-09 10.50.32 AM
1234         22/Jun/11          22-JAN-09 10.42.50 PM                   NIL
1234         23/Jun/11                  NIL                          23-JAN-09 06.50.40 AM
1234         24/Jun/11          23-JAN-09 10.49.55 PM                   NIL
1234         24/Jun/11                  NIL                       24-JAN-09 05:22:19 AM  
`

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

Ответы [ 2 ]

1 голос
/ 29 июня 2011

Простое грубое решение было бы следующим:

SELECT a.emp_number, a.time_in_out as time_in, (SELECT
   MIN(b.time_in_out)
   FROM yourtable b
   WHERE b.specifier='OUT'
   AND b.emp_number=a.emp_number
   AND b.time_in_out>=a.time_in_out) as time_out
FROM yourtable a
WHERE a.specifier='IN'
ORDER BY a.time_in_out;

Но если вы хотите подобрать дни без записей в / из, вам нужно выполнить внешнее соединение с полной таблицей дат,или используйте PL / SQL для итерации последовательности.

0 голосов
/ 04 июля 2011

попробуйте, основываясь на ответе @ symcbean - следующий запрос даст желаемый результат. Пожалуйста, дайте мне знать, если у вас есть запрос или вы хотите получить какие-либо разъяснения ((добавьте ваши комментарии))

SELECT * FROM  
       (
         SELECT emp_number,
                to_char(time_out ,'DD-MM-YYYY') day,
                decode(to_char(time_in ,'DD-MM-YYYY'),
                       to_char(time_out ,'DD-MM-YYYY'),
                       min(time_in),
                       null
                       ) time_in,
                max(time_out) time_out
         FROM (
                SELECT a.emp_number,
                a.time_in_out as time_in,
                (
                   SELECT MIN(b.time_in_out)
                   FROM t b
                   WHERE b.specifier = 'OUT'
                     AND b.emp_number = a.emp_number
                     AND b.time_in_out >= a.time_in_out
                 ) as time_out
                 FROM t a
                 WHERE a.specifier = 'IN'
                )
                group by to_char(time_in ,'DD-MM-YYYY'),to_char(time_out ,'DD-MM-YYYY'),emp_number
          union all 
          SELECT  emp_number,to_char(time_out ,'DD-MM-YYYY'),
                  max(time_in),
                  null time_out
           FROM (
                  SELECT a.emp_number,
                         a.time_in_out as time_in,
                         (
                            SELECT MIN(b.time_in_out)
                            FROM t b
                            WHERE b.specifier = 'OUT'
                            AND b.emp_number = a.emp_number
                            AND b.time_in_out >= a.time_in_out
                          ) as time_out
                          FROM t a
                          WHERE a.specifier = 'IN'
                   )
                   group by to_char(time_in ,'DD-MM-YYYY'),to_char(time_out ,'DD-MM-YYYY'),emp_number
   HAVING to_char(time_in ,'DD-MM-YYYY')<> to_char(time_out ,'DD-MM-YYYY')
   )
   ORDER BY nvl(TIME_IN,time_out)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...