powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по выборке
38 сообщений из 38, показаны все 2 страниц
Вопрос по выборке
    #38341622
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, хочу попросить Вашей помощи в таком вопросе:
Существует таблица отпусков: Дата начала отпуска, дата конца, таб. номер сотрудника.
Промежуточная таблица: таб. номер, год(к примеру 2011,2012,2013).
Нужно получить кол-во дней нахождения на больничном и периоды в каждом из годов промежуточной таблицы, причем если сотрудник был на больничном с 01.11.2011 по 02.01.2012 то в результате должно быть так:
2011г
01.11.11 - 31.12.11 | 61день
2012г.
01.01.2012 - 02.01.2012 | 2 дня.


пробовал делать через case, где @DMin= 01.01.2011, @DMax=01.01.2013, nYear=2011,2012,2013

Код: sql
1.
2.
3.
4.
5.
TabNum = tr.TabNum,
Dbeg = case when datepart(year,hol.DateBegin) < (select min(nYear) from #TRes) then @DMin else hol.DateBegin end,
Dend = case when datepart(year,hol.DateEnd) > (select max(nYear) from #TRes) then @Dmax else hol.DateEnd end,
SumDays = case when datepart(year,hol.DateBegin) < (select min(nYear) from #TRes) then datediff(day,@DMin,hol.DateEnd+1)
when datepart(year,hol.DateEnd) > (select max(nYear) from #TRes) then datediff(day,hol.DateBegin,@DMax+1)[/FIXED][/FIXED][/FIXED]



но это отрабатывает только если год начала отпуска не входит в nYear.
Как лучше поступить? Заранее спасибо!
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38341635
Фотография StarikNavy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rukesa,

зачем новую тему? в старой бы написали.
напишите скрипт создания таблиц, ввода тестовых данных (здесь же, еще тему создавать не надо)
и приведите свой ПОЛНЫЙ запрос, а не отрывок
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38341645
Mnior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рекомендации по оформлению сообщений в форуме
Не написали скрипт тестовых данных.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38341650
rukesa,

Чего-то на зал за здравие отпуска, кончил за упокой больничные
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38341651
Добрый Э - Эхrukesa,

Чего-то на зал начал за здравие отпуска, кончил за упокой больничные
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38341691
Mnior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, ладно, забей. Человек совершает тысячи ошибок в день. Хуже, когда настолько слеп, что не замечаешь их.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
WITH [HoliDays] ([From],[To],[TID]) AS (SELECT Convert(Date,[From]),Convert(Date,[To]),TID FROM (VALUES
 ('20111101','20120101',1)
,('20111101','20120601',2)
,('20100301','20100501',3)
)hd([From],[To],[TID])
), [Years] ([Year],[From]) AS (SELECT Year([From]),Convert(Date,[From]) FROM (VALUES
 ('20100101')
,('20110101')
,('20120101')
,('20130101')
)y([From])
)	SELECT	 H.TID
		,Y.[Year]
		,CASE WHEN H.[From] >                Y.[From]  THEN H.[From] ELSE                Y.[From]  END	AS [From]
		,CASE WHEN H.[To]   < DateAdd(Year,1,Y.[From]) THEN H.[To]   ELSE DateAdd(Year,1,Y.[From]) END	AS [To]
	FROM	[HoliDays]	H
	JOIN	[Years]		Y ON Y.[From] >= DateAdd(Year,-1,H.[From])
				 AND Y.[From] <  H.[To]
;

И запомните - время непрерывно .
31.12.11 - выводите так в интерфейсе, но внутрях должны фиксироваться моменты времени (2012-01-01 00:00:00.0000000) и не важно, с какой точностью тип хранения. И не важно "реальность" - главное модель.

И не думайте что вы заметили все те 42 принципа, которые использовались в написании запроса. Главное постепенно их впитывать.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38341701
Mnior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Согласен, так организовать таблицы (вычисляемые колонки) удобнее:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
WITH [HoliDays] ([From],[To],[TID]) AS (SELECT Convert(Date,[From]),Convert(Date,[To]),TID FROM (VALUES
 ('20111101','20120101',1)
,('20111101','20120601',2)
,('20100301','20100501',3)
)hd([From],[To],[TID])
), [Years] ([Year],[From],[To]) AS (SELECT Year([From]),Convert(Date,[From]),DateAdd(Year,1,Convert(Date,[From])) FROM (VALUES
 ('20100101')
,('20110101')
,('20120101')
,('20130101')
)y([From])
)	SELECT	 H.TID
		,Y.[Year]
		,CASE WHEN H.[From] > Y.[From] THEN H.[From] ELSE Y.[From] END	AS [From]
		,CASE WHEN H.[To]   < Y.[To]   THEN H.[To]   ELSE Y.[To]   END	AS [To]
	FROM	[HoliDays]	H
	JOIN	[Years]		Y ON Y.[From] >= DateAdd(Year,-1,H.[From])
				 AND Y.[From] <  H.[To]
;
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38341998
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не совсем понял 2 последних сообщения и как это относится к моему вопросу...
перепутал больничные и отпуска, так мне нужно будет и то и то, без разницы на чем пробовать.
исходные таблицы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
---------Таблица год, сотрудник             + также есть две известные переменные @DMin = '20110101' и @DMax = '20130101', --может они пригодятся
Create table #TRes (nYear int, TabNum varchar(15))

insert #TRes values(2011,'123')
insert #TRes values(2012,'123')
insert #TRes values(2013,'123')

---------Таблица больничных(дата начала, дата окончания, сотрудник)
create table #Ill (DateBegin datetime, DateEnd datetime, TabNum varchar(15))
insert #TRes values('20111204','20120301','123')
insert #TRes values('20110901','20130201','123')
insert #TRes values('20121101','20121201','123')
--Нужно получить  следующий select: Год, дата начала периода отсутствия,дата конца периода отсутствия, кол-во дней --отсутствия. 
select
  Year        = ?
  DBeg       = ?
  DEnd       = ?
  SumDays  = ?
From
  #TRes tr
  Join  #Ill il
    On il.TabNum = tr.TabNum and
         (datepart(year,il.DateBegin) in (select nYear from #TRes) or  datepart(year,il.DateEnd) in (select nYear from #TRes))


Соответственно я спрашиваю, что будет вместо "?", чтобы получить за 3 года(2011,2012,2013) периоды, в которые сотрудник болел. Т.е.
2011 | 20111204 | 20111231 | 27
2011 | 20110901 | 20111231 | 122
2012 | 20120101 | 20120301 | 61
2012 | 20120101 | 20121231 | 365
2012 | 20121101 | 20121201 | 30
2012 | 20130101 | 20130201 | 30
Надеюсь теперь стало понятнее....спасибо ответившим и поправляющим
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38342002
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
блин опять ошибся, после
Код: sql
1.
create ill

должны идти
Код: sql
1.
insert #Ill

сорри
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38342275
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никаких предложений/мыслей нет?
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38342280
Фотография Павел Воронцов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rukesa,

есть. Поищи по форуму "пересечение интервалов". Лень майкросовтовский синтаксис вспоминать просто. Не найдешь - попытаюсь вспомнить.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38342462
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо, нашел много. только вот пока никак не могу связать их со своей задачей...
похоже Mnior что-то похожее мне написал, спасибо, но что-то с синтаксисом разобраться не получается, да и опять же к своей задаче привязать не могу.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38342475
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rukesa,

для вашего последнего примера соединять таблицы надо так, например
Код: sql
1.
JOIN #Ill il ON il.TabNum = tr.TabNum AND DATEPART(Year, il.DateBegin) <= tr.nYear AND DATEPART(Year, il.DateEnd) >= tr.nYear

, получатся пересечения для каждого года. и уже для результата искать границы интервалов, обрезая выходящее за границы года tr.nYear
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38342844
efqwefqwe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rukesa,

а почему у вас данные

insert #Ill values('20111204','20120301','123')
insert #Ill values('20110901','20130201','123')
insert #Ill values('20121101','20121201','123')

имеют не пустое пересечение? что больной одновременно два раза болел? хотел запилить через window функции, но вот этот момэнт всю малину портит
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343136
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь, писал этот запрос прямо здесь, поэтому даты брал из головы. Действительно, даты не должны пересекаться. Если нужно, могу придумать новые даты.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343137
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakill, спасибо, учту
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343138
efqwefqwerukesa,

а почему у вас данные

insert #Ill values('20111204','20120301','123')
insert #Ill values('20110901','20130201','123')
insert #Ill values('20121101','20121201','123')

имеют не пустое пересечение? что больной одновременно два раза болел? хотел запилить через window функции, но вот этот момэнт всю малину портитКто мешает "однотипные" интервалы, имеющие пересечения, "склеить" в единый интервал, после чего "пилить" уже оконными функциями?
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343143
rukesa,

очень часто интервальные задачи решаются через преобразование интервалов в точки, после чего решается, как из полученного множества точек вновь собрать интервалы. :)
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343147
Добрый Э - Эх,

В целом, по сотруднику пересечение разнотиповых интервалов допускается?
К примеру, человек пошел в отпуск и в середине отпуска заболел. Ну или наоборот: заболел, а в середине болезни случился очередной отпуск.
Или такое в принципе невозможно и в каждый момент времени у сотрудника может быть ровно одно состояние: работает, отпуск, на больничном, в командировке и т.д.?
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343177
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пересечение не допускается, в примере я ошибся, когда писал интервалы.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343277
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343462
Mnior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakillrukesa,
для вашего последнего примера соединять таблицы надо так, например
Код: sql
1.
2.
3.
4.
JOIN #Ill il
ON il.TabNum = tr.TabNum
AND tr.nYear >= DATEPART(Year, il.DateBegin)
AND tr.nYear <= DATEPART(Year, il.DateEnd)

, получатся пересечения для каждого года. и уже для результата искать границы интервалов, обрезая выходящее за границы года tr.nYearДля непрерывных интервалов не может быть оба знака с равенством.
Всегда с одной стороны отрезка одна точка выколота.

А если добавятся время. Вы будете писать 23:59:59:997 ?
Вы всё равно упустите кусок времени в зависимости от точности.
----------------
Ну вот с подсчётом дней. Можно было самому дописать:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
WITH [HoliDays] ([From],[To],[TID]) AS (SELECT Convert(Date,[From]),Convert(Date,[To]),TID FROM (VALUES
 ('20111204','20120301',123)
,('20110901','20130201',124)
,('20121101','20121201',125)
)hd([From],[To],[TID])
), [Years] ([Year],[From],[To]) AS (SELECT Year([From]),Convert(Date,[From]),DateAdd(Year,1,Convert(Date,[From])) FROM (VALUES
 ('20100101')
,('20110101')
,('20120101')
,('20130101')
,('20140101')
)y([From])
)	SELECT	 H.TID
		,Y.[Year]
		,X.[From]
		,X.[To]
		,DateDiff(Day,X.[From],X.[To])	AS [Days]
	FROM	[HoliDays]	H
	JOIN	[Years]		Y ON Y.[From] >= DateAdd(Year,-1,H.[From])
				 AND Y.[From] <  H.[To]
	CROSS APPLY (SELECT
		 CASE WHEN H.[From] > Y.[From] THEN H.[From] ELSE Y.[From] END
		,CASE WHEN H.[To]   < Y.[To]   THEN H.[To]   ELSE Y.[To]   END
			)	X([From],[To])

Не нравится пример через WITH? Вот через таблы
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
DECLARE @HoliDays TABLE ([From] Date,[To] Date, [TID] Int, PRIMARY KEY ([TID],[From]))
INSERT	@HoliDays VALUES
 ('20111204','20120301',123)
,('20110901','20130201',124)
,('20121101','20121201',125)
DECLARE @Years TABLE ([Year] AS Year([From]),[From] Date PRIMARY KEY, [To] AS DateAdd(Year,1,Convert(Date,[From])))
INSERT	@Years ([From]) VALUES
 ('20100101')
,('20110101')
,('20120101')
,('20130101')
,('20140101')

SELECT	 H.TID
	,Y.[Year]
	,X.[From]
	,X.[To]
	,DateDiff(Day,X.[From],X.[To])	AS [Days]
FROM	@HoliDays	H
JOIN	@Years		Y ON Y.[From] >= DateAdd(Year,-1,H.[From])
			 AND Y.[From] <  H.[To]
CROSS APPLY (SELECT
	 CASE WHEN H.[From] > Y.[From] THEN H.[From] ELSE Y.[From] END
	,CASE WHEN H.[To]   < Y.[To]   THEN H.[To]   ELSE Y.[To]   END
		)	X([From],[To])



Зачем нужна таблица (год, сотрудник)? Хватает просто список годов, для разделения.

И что тут ещё мусолить?
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343467
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый Э - Эх,
Огромное спасибо! Это-то я и пытался все получить, пробовал и курсором и через case, да все никак.
также большое спасибо всем ответившим!
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343546
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MniorShakillrukesa,
для вашего последнего примера соединять таблицы надо так, например
Код: sql
1.
2.
3.
4.
JOIN #Ill il
ON il.TabNum = tr.TabNum
AND tr.nYear >= DATEPART(Year, il.DateBegin)
AND tr.nYear <= DATEPART(Year, il.DateEnd)

, получатся пересечения для каждого года. и уже для результата искать границы интервалов, обрезая выходящее за границы года tr.nYearДля непрерывных интервалов не может быть оба знака с равенством.
Всегда с одной стороны отрезка одна точка выколота.

А если добавятся время. Вы будете писать 23:59:59:997 ?
Вы всё равно упустите кусок времени в зависимости от точности.

а зачем усложнять задачу?
если в опорной таблице только номера годов, то для проверки попадания в заданный год подходят нестрогие сравнения (и неважно, есть в таблице больничных время или нет) и это самый простой вариант.
можно, конечно, поступить другим образом - преобразовать номер года в начало года (включаем) и начало следующего года (его не включаем), но это общий подход и код бы получился несколько сложнее, смысла тут нет
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343551
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
действительно, время в данной таблице всегда 00:00:00.000
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343557
rukesa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемый Mnior,
может быть Ваш способ и лучше, но, к сожалению, мне пока не хватает знаний понять синтаксис запроса, квадратные скобки ставят меня в тупик) спасибо
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343566
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rukesaУважаемый Mnior,
может быть Ваш способ и лучше, но, к сожалению, мне пока не хватает знаний понять синтаксис запроса, квадратные скобки ставят меня в тупик) спасибоYEAR, FROM, TO - это, вообще-то, ключевые слова TSQL.
То, что они как-то обрабатываются в качестве имён полей таблицы сервером, - бонус с его стороны,
на который нельзя всегда полагаться.
Если имена объектов содержат недопустимые символы или ключевые слова,
их надо заключить в двойные кавычки (если SET QUOTED_IDENTIFIER ON)
или в квадратные скобки (они работают всегда)
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38343854
fwqefwqfrg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
with tres as
(
	select *
	from (
			values
			(2011,'123'),
			(2012,'123'),
			(2013,'123')
		) as d(yr, tid)
),
ill as
(
	select *
	from
	(
		values
		(cast('20111204' as datetime), cast('20120301' as datetime), '123'),
		(cast('20110901' as datetime), cast('20130201' as datetime), '123'),
		(cast('20121101' as datetime), cast('20121201' as datetime), '123')
	) d(db, de, tid)
),
step1 as
(
	select
		t1.tid,
		case when n = 1 then t1.db else t1.de end as dt,
		case when n = 1 then +1 else -1 end as b_e_flag
	from
		ill t1
			cross join 
		(
		 select 1
			union all
		 select 2
		) as t2(n)
),
step2 as
(
	-- учитываем, что промежутки в ill могут пересекаться, если не могут, то можно проще
	select tid, dt, b_e_flag
	from
	(
		select *, sum(b_e_flag) over(partition by tid order by dt) a_cnt
		from step1
	) t1
	where (a_cnt = 0 and b_e_flag = -1) or (a_cnt = 1 and b_e_flag = 1)

	union all

	select
		t1.tid,
		case when n = 1 then datefromparts(t1.yr, 01, 01) else datefromparts(t1.yr, 12, 31) end as dt,
		case when n = 1 then +1 else -1 end as b_e_flag
	from
		tres t1
			cross join 
		(
		 select 1
			union all
		 select 2
		) as t2(n)

)
select tid, year(min(dt)) as yr, min(dt) as bd, max(dt) as ed, datediff(d, min(dt), max(dt)) as cnt
from
(
	select tid, dt, (row_number() over(partition by tid order by dt) - 1) / 2 as g
	from
	(
		select *, sum(b_e_flag) over(partition by tid order by dt) as a_cnt
		from step2
	) t1
	where (a_cnt = 2 and b_e_flag = 1) or (a_cnt = 1 and b_e_flag = -1)
) t2
group by tid, g
order by tid, bd
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344026
Mnior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shakillа зачем усложнять задачу?Где?
Наоборот, упрощаю. Есть одна модель понимания - и все "формулы" становятся одинаковыми во всех 100500 разнообразных задачах и главное простыми. И читаются мгновенно.

А так, "А тут у нас нет у даты времени, так давайте сделаем всё по другому и вымучаем формулы"
Как в анекдоте:
- В командирских часах 8 стрелок.
- Зачем?
- 4-ре для дезориентации противника!
Shakillесли в опорной таблице ...., то для проверки ...
... и это самый простой вариантГде он проще? Посмотрите на мой запрос - он что сложнее?
Ваш сложнее, ибо надо всё понять через призму множества всяких "если-то".

Shakillно это общий подход и код бы получился несколько сложнееГде?
Вы мне ответьте где сложнее? Конкретно.

rukesaдействительно, время в данной таблице всегда 00:00:00.000Зачем вам об этом думать, есть там оно или нет?
Завтра придёт заказчик и скажет "А давайте будет"
И всё, ваш код уже не работает. Смысл.

Вы не путайте объективное "проще", от вашего субъективного. Не умеет кого-то пользоваться молотком, не значит что надо всегда бить гвозди микроскопом.
Ага, педалью "газ" умею пользоваться, а вот "тормоз" не понимаю?! Надо знать то чем пользуетесь, т.е. базовые основы скуля и MSSQL.

авторможет быть Ваш способ и лучше, но, к сожалению, мне пока не хватает знаний понять синтаксис запроса, квадратные скобки ставят меня в тупик)Да неужели вы решили задать вопрос?! Как-то нестандартно для гуманитария. Обычно у них "непонятное - игнорируй". А также, "не важен результат, и на сколько он хорош/правилен, главное что галочка есть и 'мне нравиться'".
Надеюсь что уже стало понятно. Но вопросы можно задавать. Разрешаю.
"ставят меня в тупик" - у не нормальных людей обычно "появляются вопросы, которые так приятно познать", притом познать в первую очередь самому, чтобы эту познавалку развить, чтобы догадываться до всего на свете самому.

fwqefwqfrg , BrainFuck ?
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344126
fwqefwqfrg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mnior, хотелось выписаться (от слова писАть) :D
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344139
efqwefqwe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mnior,

на самом деле хотелось сделать, чтобы каждая таблица были считаны по одному разу. Но вылезла куча сортировок и не каким индексом не поправить это так как последовательность дат из разных таблиц. Вобщем выложил что есть для Brain Fuck'a...
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344212
fwqefwqfrg
Код: sql
1.
	-- учитываем, что промежутки в ill могут пересекаться, если не могут, то можно проще



Как вариант объединения пересекающихся и входящих друг в друга интервалов
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344451
Mnior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
efqwefqweхотелось сделать, чтобы каждая таблица были считаны по одному разуБоже.
А не было задачи написать запрос чтобы букв A было чётным?!

Единственный смысл таблицы годов как раз и считываться много раз - делить отрезки на куски.
Изначальный смысл вещей ничто не должно затмевать, тем более всякие симулякры.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344459
jfjfjkgkgkdkd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый Э - Эхfwqefwqfrg
Код: sql
1.
	-- учитываем, что промежутки в ill могут пересекаться, если не могут, то можно проще



Как вариант объединения пересекающихся и входящих друг в друга интервалов

Спасибо за такой вариант. Хорошо, можно не преобразуя таблицу сразу все считать. И за сайт тоже, не знал про него.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344468
wefqwefq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mnior, согласен

MniorЕдинственный смысл таблицы годов как раз и считываться много раз - делить отрезки на куски.


Хм. А может обращаться к таблице каникул N раз, где N - количество годов в таблице годов?
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38344594
=)8)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
OFFTOP лучше 10 раз по разу, чем ни разу 10 раз
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38345194
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оффтоп 2 MniorMniorShakillно это общий подход и код бы получился несколько сложнее
Где?
Вы мне ответьте где сложнее? Конкретно.

моя подсказка была для исходных данных из 14609975 этого сообщения. то есть автору оставалось дописать только select к тому что он уже сделал. принципиальных отличий нет, и я думаю ТС способен понять на примерах нюансы типа того, когда надо включать границы интервалов, а когда - наоборот.

но непонятно, зачем по такой мелочи вы пишете столько много букв.
...
Рейтинг: 0 / 0
Вопрос по выборке
    #38346070
Mnior
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wefqwefqХм. А может обращаться к таблице каникул N раз, где N - количество годов в таблице годов?Вы хотите решить статистическую задачу?

Перед этим надо проверить осмысленность задачи. И практически задача ТС не имеет смысла. Обычно собирается данные за один год, для подсчёта.

Во вторых, надо понимать первую проблему диапазонов в скуле: Модель с двумя полями (From,To) нормально не оптимизируется, ибо индексы линейны, см подробности ( 12610105 ).
Т.е. поиск, аля: From >= X AND To < Y - вываливается в полу-скан.
В моём случае диапазон указывается по одному полю: From >= Y AND From < Y что сильно ограничивает скан (в основном до одного значения).

В третьих Статистически количество годов намного больше, чем пересечений года в диапазонах. Отпуска более года вообще редкость. Соответственно полу-сканы ещё менее покрываемы

Поэтому, предлагаемый вами "обратный вариант" будет обрабатывать заметно больше строк.

В четвёртых, эти данные собираются для конкретной цели, для которых порядок данных может быть существенный. В вашем случае жёсткий порядок сбора и объединение смешивает карты и может добавить дополнительные большие ресурсы сортировки.
В моём случае порядок данных отпусков неважен, не определяется и не навязывается.

В пятых, я говорил про множественное считывание, о его неизбежности, ибо эта задача о генерации данных, а не к примеру "слиянии". И тут уже не важно, повторно считывается Года или Отпуска - те же яйца, только в профиль.

В шестых, запрос должен быть декларативным, и сервер должен сам выбирать порядок соединения. Но к сожалению не всякое выражение декларативно для сервера, но если появятся соответствующие оптимизации (что вероятно, т.к. функция детерминирована и линейна), то можно сказать что я не задаю порядок соединения. К тому же его можно поменять простой перестановкой.
эквивалентное выражение
Код: sql
1.
2.
3.
Y.[From] >= DateAdd(Year,-1,H.[From])
-- =>
DateAdd(Year,1,Y.[From]) >= H.[From]

...
Рейтинг: 0 / 0
38 сообщений из 38, показаны все 2 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по выборке
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]