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

Откуда:
Сообщений: 12
Добрый день. Помогите пожалуйста советом или ссылкой на статью, которая поможет решить мою задачу.

У меня есть табличка с данными(рисунок 1), которую нужно преобразовать в другой вид (рисунок 2).
Прошу подсказать мне как лучше сделать? Через case прописывать даты начала и окончания или есть другие способы?

К сообщению приложен файл. Размер - 4Kb
5 май 16, 13:35    [19138285]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
vesnushka
Member

Откуда:
Сообщений: 12
Рисунок 2

К сообщению приложен файл. Размер - 3Kb
5 май 16, 13:36    [19138289]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
Glory
Member

Откуда:
Сообщений: 104751
vesnushka
Прошу подсказать мне как лучше сделать?

Лучше всего это делается начиная с нормальной постановки задачи.
Преобразовать одно в другое - это не постановка задачи.
5 май 16, 13:39    [19138300]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
vesnushka
Member

Откуда:
Сообщений: 12
Glory, Постановка задачи: сгруппировать данные таким образом, чтобы в одной строке находились сотрудники разных отделов, если период начала работы над определенной услугой начинается в одну и ту же дату с другим сотрудником, либо находится между датами начала и окончания работ. За дату начала берется более ранняя работа, при условии что услуга совпадает. За дату окончания так же берется более ранняя дата из двух сотрудников. Если сравнить рисунки, то станет понятно что именно нужно сделать. Думала визуально понятнее будет.
5 май 16, 14:32    [19138571]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
Glory
Member

Откуда:
Сообщений: 104751
vesnushka
Постановка задачи: сгруппировать данные таким образом, чтобы в одной строке находились сотрудники разных отделов, если период начала работы над определенной услугой начинается в одну и ту же дату с другим сотрудником, либо находится между датами начала и окончания работ. За дату начала берется более ранняя работа, при условии что услуга совпадает. За дату окончания так же берется более ранняя дата из двух сотрудников. Если сравнить рисунки, то станет понятно что именно нужно сделать. Думала визуально понятнее будет.

И что будет, если начавшихся одновременно начавшихся периодов больше двух ? А если у них еще и оба сотрудника заполнены ?
И почему в вашем примере объединены 1ый и 2ой пероиоды,а не 2ой и 3ий ?
Ведь 3ий пероид "находится между датами начала и окончания работ" 2го периода.
5 май 16, 14:37    [19138604]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
vesnushka
Member

Откуда:
Сообщений: 12
Glory,
объединены и первый второй, и второй третий. Это можно увидеть по сотрудникам. Вместо NULL в графе "Сотрудник ТК" теперь "Сидоров", я немного перепутала в прошлом ответе, за дату начала берется более поздняя дата из двух периодов, а за дату окончания более ранняя из двух. Оба сотрудника заполнены не могут быть, именно поэтому мне и надо их объединить.
6 май 16, 01:20    [19140695]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
iljy
Member

Откуда:
Сообщений: 8711
vesnushka,

у вас обычная задача на пересечение интервалов. Решается примерно так
declare @t1 table (b date, e date, name varchar(100))
declare @t2 table (b date, e date, name varchar(100))

insert @t1 values
('20140703', '20140714', 'N1'),('20140714', '20140729', 'N2')
insert @t2 values
('20140703', '20140729', 'P1')

select *
from @t1 t1 join @t2 t2 on t1.b <= t2.e and t2.b <= t1.e
6 май 16, 02:01    [19140716]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
Glory
Member

Откуда:
Сообщений: 104751
vesnushka
объединены и первый второй, и второй третий. Это можно увидеть по сотрудникам. Вместо NULL в графе "Сотрудник ТК" теперь "Сидоров", я немного перепутала в прошлом ответе, за дату начала берется более поздняя дата из двух периодов, а за дату окончания более ранняя из двух. Оба сотрудника заполнены не могут быть, именно поэтому мне и надо их объединить.

Что насчет ответов на другие вопросы ?
А то у вас на картинке просто идеальный вариант - 3 периода аккуратьненько так вписываьтся друг в друга.
6 май 16, 08:16    [19140848]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
vesnushka
Member

Откуда:
Сообщений: 12
iljy,

Спасибо просто огромное!! Написала запрос подобный вашему, отрабатывает почти правильно, за исключением тех моментов, где у одного сотрудника дата начала меньше даты начала второго сотрудника, а даты окончания у них одинаковые. Интервальное пересечение верное, но дата окончания сотрудника, у которого дата начала работ более ранняя, неверная.
Например сотрудник1(петров)трудился с 01.02.2016 по 10.02.2016 над определенной задачей, сотрудник другого отдела (сотрудник2-иванов), приступил к работе над этой задачей 6.02.2016 и закончил 10.02.2016.
Результат запроса должен выводить:
Дата начала: 01.02.2016 дата окончания: 06.02.2016 сотрудник1: петров сотрудник2: Null
Дата начала:06.02.2016 дата окончания 10.02.2016 сотрудник1: петров сотрудник2: иванов

А выводит:
Дата начала:01.02.2016 дата окончания: 10.02.2016 сотрудник1: петров сотрудник2: Null
Дата начала:06.02.2016 дата окончания 10.02.2016 сотрудник1: петров сотрудник2: иванов

Можно ли это как-то исправить?
17 май 16, 09:00    [19181765]     Ответить | Цитировать Сообщить модератору
 Re: MS SQL Server 2014  [new]
iljy
Member

Откуда:
Сообщений: 8711
vesnushka,

это как раз то, о чем говорил Glory. Я написал запрос для ваших "идеальных" данных, запрос будет сложнее, потому что сначала надо все интервалы вытащить

declare @t1 table (b date, e date, name varchar(100))
declare @t2 table (b date, e date, name varchar(100))

insert @t1 values
('20140603', '20140714', 'N1'),('20140714', '20140729', 'N2')
insert @t2 values
('20140703', '20140729', 'P1')

;with cte as
(
	select ROW_NUMBER() over(order by i) rn, i
	from (
		select b i from @t1 union
		select e from @t1 union
		select b from @t2 union
		select e from @t2
	) t
)
select *
from(
	select t1.i b, t2.i e from cte t1 join cte t2 on t1.rn + 1 = t2.rn
) t left join @t1 t1 on t1.b < t.e and t1.e > t.b
	left join @t2 t2 on t2.b < case when t.e > t1.e then t1.e else t.e end and
					    t2.e > case when t.b < t1.b then t1.b else t.b end
17 май 16, 10:49    [19182345]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить