Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Организовать запрос  [new]
birk
Member

Откуда: Mother Russia
Сообщений: 207
Есть таблица:
01.01.2011 Сотрудник1 Больничный
02.01.2011 Сотрудник1 Больничный
03.01.2011 Сотрудник1 Больничный
04.01.2011 Сотрудник1 Отпуск
05.01.2011 Сотрудник1 Отпуск
06.01.2011 Сотрудник1 Отпуск

Нужно получить:
Сотрудник1 | Больничный | С 01.01.2011 По 03.01.2011
Сотрудник1 | Отпуск | С 04.01.2011 По 06.01.2011
9 фев 12, 15:36    [12063274]     Ответить | Цитировать Сообщить модератору
 Re: Организовать запрос  [new]
Гузы
Guest
birk,
select f1,f2,'text1' +cast(min(f0) as varchar)+' - '+cast(max(f0) as varchar) from table1
group by f1,f2
9 фев 12, 15:43    [12063384]     Ответить | Цитировать Сообщить модератору
 Re: Организовать запрос  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2423
birk,

select max(...) , min(...) from ... group by ...
9 фев 12, 15:43    [12063390]     Ответить | Цитировать Сообщить модератору
 Re: Организовать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
WarAnt
birk,

select max(...) , min(...) from ... group by ...
Так не получится.
birk, небось, непрерывные интервалы хочет.
Периоды больничных, наверно, чередуются с периодами отпусков и проч. неоднократно
9 фев 12, 16:03    [12063685]     Ответить | Цитировать Сообщить модератору
 Re: Организовать запрос  [new]
Добрый Э - Эх
Guest
iap, Зато вот так будет работать:
with
-- Набор тестовых данных:
  b$m_test (x_num, emp_name, emp_status) as
    (
      select  1, 'Сотрудник1', 'Больничный' union all
      select  2, 'Сотрудник1', 'Больничный' union all
      select  3, 'Сотрудник1', 'Больничный' union all
      select  4, 'Сотрудник1', 'Отпуск' union all
      select  5, 'Сотрудник1', 'Отпуск' union all
      select  6, 'Сотрудник1', 'Отпуск' union all
      select  7, 'Сотрудник1', 'Отпуск' union all
      select  8, 'Сотрудник1', 'Отпуск' union all
      select  9, 'Сотрудник1', 'Отпуск' union all
      select 10, 'Сотрудник1', 'Отпуск' union all
      select 11, 'Сотрудник1', 'Отпуск' union all
      select 12, 'Сотрудник1', 'Больничный' union all
      select 13, 'Сотрудник1', 'Больничный' union all
      select 14, 'Сотрудник1', 'Больничный' union all
      select 15, 'Сотрудник1', 'Больничный' union all
      select 16, 'Сотрудник1', 'Работает' union all
      select 17, 'Сотрудник1', 'Работает' union all
      select 18, 'Сотрудник1', 'Работает' union all
      select 19, 'Сотрудник1', 'Работает' union all
      select 20, 'Сотрудник1', 'Отпуск' union all
      select 21, 'Сотрудник1', 'Отпуск' union all
      select 22, 'Сотрудник1', 'Отпуск' union all
      select 23, 'Сотрудник1', 'Отпуск' union all
      select 24, 'Сотрудник1', 'Отпуск' union all
      select 25, 'Сотрудник1', 'Отпуск' union all
      select 26, 'Сотрудник1', 'Больничный' union all
      select 27, 'Сотрудник1', 'Больничный' union all
      select 28, 'Сотрудник1', 'Работает' union all
      select 29, 'Сотрудник1', 'Работает' union all
      select 30, 'Сотрудник1', 'Работает' union all
      select  1, 'Сотрудник2', 'Больничный' union all
      select  2, 'Сотрудник2', 'Больничный' union all
      select  3, 'Сотрудник2', 'Больничный' union all
      select  4, 'Сотрудник2', 'Больничный' union all
      select  5, 'Сотрудник2', 'Больничный' union all
      select  6, 'Сотрудник2', 'Больничный' union all
      select  7, 'Сотрудник2', 'Отгул' union all
      select  8, 'Сотрудник2', 'Отгул' union all
      select  9, 'Сотрудник2', 'Отгул' union all
      select 10, 'Сотрудник2', 'Отгул' union all
      select 11, 'Сотрудник2', 'Отгул' union all
      select 12, 'Сотрудник2', 'Больничный' union all
      select 13, 'Сотрудник2', 'Больничный' union all
      select 14, 'Сотрудник2', 'Больничный' union all
      select 15, 'Сотрудник2', 'Больничный' union all
      select 16, 'Сотрудник2', 'Работает' union all
      select 17, 'Сотрудник2', 'Работает' union all
      select 18, 'Сотрудник2', 'Работает' union all
      select 19, 'Сотрудник2', 'Работает' union all
      select 20, 'Сотрудник2', 'Отпуск' union all
      select 21, 'Сотрудник2', 'Отпуск' union all
      select 22, 'Сотрудник2', 'Отпуск' union all
      select 23, 'Сотрудник2', 'Работает' union all
      select 24, 'Сотрудник2', 'Работает' union all
      select 25, 'Сотрудник2', 'Работает' union all
      select 26, 'Сотрудник2', 'Больничный' union all
      select 27, 'Сотрудник2', 'Больничный' union all
      select 28, 'Сотрудник2', 'Работает' union all
      select 29, 'Сотрудник2', 'Работает' union all
      select 30, 'Сотрудник2', 'Работает'
    )
--
-- Основной запрос:
select emp_name, emp_status, 
       'С ' + cast(MIN(x_num) as varchar) +
       ' по ' + cast(MAX(x_num) as varchar) as x_range
  from (
         select x_num, emp_name, emp_status,
                ROW_NUMBER() over(partition by emp_name, emp_status order by x_num) -
                ROW_NUMBER() over(partition by emp_name order by x_num) as grp_id
           from b$m_test
       ) as v
 group by emp_name, emp_status, grp_id
 order by emp_name, MIN(x_num)

--
-- Результат запроса:
Query finished, retrieving results...

 EMP_NAME    EMP_STATUS   X_RANGE
----------   ----------   ----------
Сотрудник1   Больничный   С 1 по 3
Сотрудник1   Отпуск       С 4 по 11
Сотрудник1   Больничный   С 12 по 15
Сотрудник1   Работает     С 16 по 19
Сотрудник1   Отпуск       С 20 по 25
Сотрудник1   Больничный   С 26 по 27
Сотрудник1   Работает     С 28 по 30
Сотрудник2   Больничный   С 1 по 6
Сотрудник2   Отгул        С 7 по 11
Сотрудник2   Больничный   С 12 по 15
Сотрудник2   Работает     С 16 по 19
Сотрудник2   Отпуск       С 20 по 22
Сотрудник2   Работает     С 23 по 25
Сотрудник2   Больничный   С 26 по 27
Сотрудник2   Работает     С 28 по 30

15 row(s) retrieved



2 birk тока это, x_num у меня INT, но сути это не меняет. Если у тебя датя именно даты, а не строки, то проблем не возникнет.
10 фев 12, 06:48    [12066851]     Ответить | Цитировать Сообщить модератору
 Re: Организовать запрос  [new]
Igethim
Member

Откуда: Город 312
Сообщений: 75
Супер решение Добрый Э - Эх!

Мой запрос сложнее, но если это не SQL Server 2005 и выше, можно так (воспользуюсь твоим же примером):

create table #source_table
(
date_effective datetime,
emp_name varchar(50),
emp_status varchar(50)
)

insert #source_table (date_effective, emp_name, emp_status)
(
select '2011-01-01', 'Employee1', 'Sick leave' union all
select '2011-01-02', 'Employee1', 'Sick leave' union all
select '2011-01-03', 'Employee1', 'Sick leave' union all
select '2011-01-04', 'Employee1', 'Vacation leave' union all
select '2011-01-05', 'Employee1', 'Vacation leave' union all
select '2011-01-06', 'Employee1', 'Vacation leave' union all
select '2011-01-07', 'Employee1', 'Vacation leave' union all
select '2011-01-08', 'Employee1', 'Vacation leave' union all
select '2011-01-09', 'Employee1', 'Vacation leave' union all
select '2011-01-10', 'Employee1', 'Vacation leave' union all
select '2011-01-11', 'Employee1', 'Vacation leave' union all
select '2011-01-12', 'Employee1', 'Sick leave' union all
select '2011-01-13', 'Employee1', 'Sick leave' union all
select '2011-01-14', 'Employee1', 'Sick leave' union all
select '2011-01-15', 'Employee1', 'Sick leave' union all
select '2011-01-16', 'Employee1', 'Working' union all
select '2011-01-17', 'Employee1', 'Working' union all
select '2011-01-18', 'Employee1', 'Working' union all
select '2011-01-19', 'Employee1', 'Working' union all
select '2011-01-20', 'Employee1', 'Vacation leave' union all
select '2011-01-21', 'Employee1', 'Vacation leave' union all
select '2011-01-22', 'Employee1', 'Vacation leave' union all
select '2011-01-23', 'Employee1', 'Vacation leave' union all
select '2011-01-24', 'Employee1', 'Vacation leave' union all
select '2011-01-25', 'Employee1', 'Vacation leave' union all
select '2011-01-26', 'Employee1', 'Sick leave' union all
select '2011-01-27', 'Employee1', 'Sick leave' union all
select '2011-01-28', 'Employee1', 'Working' union all
select '2011-01-29', 'Employee1', 'Working' union all
select '2011-01-30', 'Employee1', 'Working' union all
select '2011-01-01', 'Employee2', 'Sick leave' union all
select '2011-01-02', 'Employee2', 'Sick leave' union all
select '2011-01-03', 'Employee2', 'Sick leave' union all
select '2011-01-04', 'Employee2', 'Sick leave' union all
select '2011-01-05', 'Employee2', 'Sick leave' union all
select '2011-01-06', 'Employee2', 'Sick leave' union all
select '2011-01-07', 'Employee2', 'Day off' union all
select '2011-01-08', 'Employee2', 'Day off' union all
select '2011-01-09', 'Employee2', 'Day off' union all
select '2011-01-10', 'Employee2', 'Day off' union all
select '2011-01-11', 'Employee2', 'Day off' union all
select '2011-01-12', 'Employee2', 'Sick leave' union all
select '2011-01-13', 'Employee2', 'Sick leave' union all
select '2011-01-14', 'Employee2', 'Sick leave' union all
select '2011-01-15', 'Employee2', 'Sick leave' union all
select '2011-01-16', 'Employee2', 'Working' union all
select '2011-01-17', 'Employee2', 'Working' union all
select '2011-01-18', 'Employee2', 'Working' union all
select '2011-01-19', 'Employee2', 'Working' union all
select '2011-01-20', 'Employee2', 'Vacation leave' union all
select '2011-01-21', 'Employee2', 'Working' union all
select '2011-01-22', 'Employee2', 'Working' union all
select '2011-01-23', 'Employee2', 'Working' union all
select '2011-01-24', 'Employee2', 'Sick leave' union all
select '2011-01-25', 'Employee2', 'Sick leave' union all
select '2011-01-26', 'Employee2', 'Working' union all
select '2011-01-27', 'Employee2', 'Working' union all
select '2011-01-28', 'Employee2', 'Working'
)

select s1.emp_name, s1.emp_status, s1.date_effective as StartDate1, s2.date_effective as EndDate2,
DATEDIFF(d,s1.date_effective, s2.date_effective)+1 as [Length]/*,
CAST(s3.date_effective as CHAR(12)) StartDate3,
CAST(s3.date_effective as CHAR(12)) EndDate3*/
from #source_table s1, #source_table s2, #source_table s3
where s1.emp_name = s2.emp_name and s1.emp_status = s2.emp_status and s1.date_effective <= s2.date_effective
and s1.emp_name = s3.emp_name and s1.emp_status = s3.emp_status and s3.date_effective between s1.date_effective and s2.date_effective
and not exists ( select *
from #source_table s4
where s4.emp_name = s1.emp_name and s4.emp_status = s1.emp_status
and dateadd(d, 1, s2.date_effective) = s4.date_effective)
and not exists ( select *
from #source_table s5
where s5.emp_name = s1.emp_name and s5.emp_status = s1.emp_status
and dateadd(d, -1, s1.date_effective) = s5.date_effective )
group by s1.emp_name, s1.emp_status, s1.date_effective, s2.date_effective
having SUM(datediff(d,s3.date_effective, s3.date_effective)) + count(*) = DATEDIFF(d, s1.date_effective, s2.date_effective) + 1
10 фев 12, 08:24    [12066954]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить