Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Maestro NV Member Откуда: Сообщений: 9 |
Признаться, со своим вопросом даже не знал, как правильно тему написать. Для отчёта создаётся временная табличка-календарик со списком дат и количеством пападаний. Для примера: declare @temp table (D date, X int default 0) insert into @temp (D) values ('01.01.18'), ('02.01.18'), ('03.01.18'), ('04.01.18'), ('05.01.18'), ('06.01.18') Есть другая табличка в которой имеются записи с указанием периода работы. Начальная и конечная даты. create table periods (S date, E date) insert into periods values ('25.10.17', '05.01.18'), ('20.04.16', '30.10.17'), ('02.01.18', '05.01.18'), ('08.01.18', '09.01.18'), ('03.01.18', '10.01.18') Записей сотни тысяч за несколько лет. Они могут полностью попадать в расчётный период или частично. Или вообще не попадать: Хочется узнать, есть ли элегантный способ обновления временной таблички при такой ситуации? Что бы для каждого дня подсчитать количество записей, попавших в диапазон? Не считая варианта с курсором в голову приходи такой вариант: update t set X = (select count(*) from periods where t.D between S and E) from @temp t Но это хорошо для такого простого варианта. А когда реальный подзапрос состоит не из одной таблички, а из множества связанных с большим количеством условий, то такой вариант уже работает очень тяжело. Особенно когда надо сделать выборку за несколько месяцев. Как вариант сперва попробовать нужные записи из этой выборки вытащить ещё в одну временную табличку и уже потом её использовать в подзапросе. Но мне интересно, может быть есть какой-то более простой способ всё это подсчитать не делая подзапросы по каждому дню отдельно? |
10 янв 18, 08:35 [21092101] Ответить | Цитировать Сообщить модератору |
Akina Member Откуда: Зеленоград, Москва, Россия Сообщений: 21042 |
А что там с индексами на таблицах? Если их нет (как показано) - то как ни делай, всё одно хреново получится. А если их есть - то надо верстать решение в зависимости от того, каких именно их есть. |
||
10 янв 18, 09:12 [21092187] Ответить | Цитировать Сообщить модератору |
Добрый Э - Эх
Guest |
Maestro NV, почитай про Merge. |
10 янв 18, 09:19 [21092206] Ответить | Цитировать Сообщить модератору |
Добрый Э - Эх
Guest |
Maestro NV, в твоем исходном тестовом примере решение могло бы выглядеть примерно так: merge into @temp d using ( select t.D, count(1) as cnt from @temp t join periods p on t.d between p.s and p.e group by t.d ) s on (d.d = s.d) when matched then update set d.x = s.cnt; |
10 янв 18, 09:36 [21092283] Ответить | Цитировать Сообщить модератору |
Maestro NV Member Откуда: Сообщений: 9 |
Спасибо за наводку. Как-то так получилось, что про merge ничего и не знаю. Надо изучить. |
||
10 янв 18, 11:45 [21092820] Ответить | Цитировать Сообщить модератору |
Руслан Дамирович Member Откуда: Резиновая нерезиновая Сообщений: 942 |
|
|
10 янв 18, 11:49 [21092841] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |