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

Откуда:
Сообщений: 33
Привет всем, подскажите пожалуйста как организовать выбоку для прохода по периоду дат для вывода каждой даты с определенным значением. Если такового не имеем ("0"/NULL - там есть дефолт для поля=))) ) вставить стандартное

К примеру:
Картинка с другого сайта.

Имеем таблицу:
CREATE TABLE [dbo].[RoomRatesRelation]
(
   [ID] [uniqueidentifier] NOT NULL,
   [RoomID] [BIGINT] NOT NULL,
   [RateID] [BIGINT] NOT NULL,
   [Discount] [money] NOT NULL,
   [StartDate] [datetime] NOT NULL,
   [EndDate] [datetime] NOT NULL,
   [IsActive] [bit] NOT NULL,
   [CreationDate] [datetime] NOT NULL
)


с такими данными:

   RoomID  RateID  Discount    StartDate   EndDate
   103716801   3011657 20.00   2014-09-30 00:00:00.000 2014-10-05 00:00:00.000
   103716801   3011657 0.00    2014-09-28 00:00:00.000 2014-10-26 00:00:00.000
   103716801   3011657 40.00   2014-09-29 00:00:00.000 2014-10-03 00:00:00.000


необходимо выбрать вот такое:

9/27/2014 103716801 3011657 0
9/28/2014 103716801 3011657 0
9/29/2014 103716801 3011657 40
9/30/2014 103716801 3011657 20
10/1/2014 103716801 3011657 20
10/2/2014 103716801 3011657 20
10/3/2014 103716801 3011657 20
10/4/2014 103716801 3011657 20
10/5/2014 103716801 3011657 20
10/6/2014 103716801 3011657 20
10/7/2014 103716801 3011657 0


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

Желательно сделать средствами сиквела - но можно и СИ Шарпа, Си (++/обджектив).

Спасибо.

ЗЫ: Нашел вот такую штуку для вывода каждодневного значения - но что то пипец как долго работает

DECLARE @dt1 Datetime=getdate()
DECLARE @dt2 Datetime='2014-10-26 00:00:00.000'
 
;WITH ctedaterange 
     AS (SELECT [rn]=Row_number() 
                       OVER( 
                         ORDER BY (SELECT NULL)) 
         FROM   sys.objects a 
                CROSS JOIN sys.objects b 
                CROSS JOIN sys.objects c 
                CROSS JOIN sys.objects d) 
SELECT Dateadd(dd, rn, @dt1) as [EachDay], '103716801' as [Room],	'3011657' as [Rate],	'20.00' as [Discount]
FROM   ctedaterange ut 



остальное пока не осилил - в общем жду предложений и всего прочего

ещё раз огромное спасибо.
2 окт 14, 14:45    [16650673]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Вот незадачка - что все перехали на Stackoverflow (((((
2 окт 14, 16:32    [16651494]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4900
YeaRmiX
ЗЫ: Нашел вот такую штуку для вывода каждодневного значения - но что то пипец как долго работает



Так загоните результат в таблицу и сделайте на ней индекс.
2 окт 14, 16:36    [16651515]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8819
Создайте календарь, далее элементарный джойн с таблицей диапазонов.
2 окт 14, 16:39    [16651533]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
a_voronin
Так загоните результат в таблицу и сделайте на ней индекс.

Спасибо.
Владислав Колосов
Создайте календарь, далее элементарный джойн с таблицей диапазонов.

Спасибо

но вот что делать с выборкой пиковых значений.
2 окт 14, 17:05    [16651718]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
DECLARE
 @iBeginDate DATE,
 @iEndDate DATE
 
SELECT    
 @iBeginDate = getdate()
,@iEndDate = '2014-10-26 00:00:00.000';
 
WITH Calendar AS (
SELECT @iBeginDate AS tDate
UNION ALL
SELECT dateadd(DAY , 1, tDate) AS tDate
FROM Calendar
WHERE dateadd (DAY, 1, tDate) <= @iEndDate
)
 
SELECT c.tDate, r.*
FROM Calendar c
INNER JOIN roomratesrelation r on c.tDate between r.StartDate and r.EndDate
OPTION (MAXRECURSION 0)


И как жить дальше))))
2 окт 14, 17:23    [16651836]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Блин, кажется я все ближе и ближе

DECLARE
 @iBeginDate DATE,
 @iEndDate DATE
 
SELECT    
 @iBeginDate = getdate()
,@iEndDate = Dateadd(dd, 30, getdate());
 
WITH Calendar AS (
SELECT @iBeginDate AS tDate
UNION ALL
SELECT dateadd(DAY , 1, tDate) AS tDate
FROM Calendar
WHERE dateadd (DAY, 1, tDate) <= @iEndDate
)

SELECT c.tDate, t.*
FROM Calendar c
OUTER APPLY (select top 1 * from roomratesrelation where startdate <= c.tDate and c.tDate between startdate and enddate order by StartDate DESC) t 
OPTION (MAXRECURSION 0)
2 окт 14, 19:25    [16652478]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
как теперь побороть NULL значения в

2014-10-25	103716801	3011657	0.00	2014-09-28 00:00:00.000	2014-10-26 00:00:00.000
2014-10-26	103716801	3011657	0.00	2014-09-28 00:00:00.000	2014-10-26 00:00:00.000
2014-10-27	NULL	NULL	NULL	NULL	NULL	NULL
2014-10-28	NULL	NULL	NULL	NULL	NULL	NULL
2014-10-29	NULL	NULL	NULL	NULL	NULL	NULL
2014-10-30	NULL	NULL	NULL	NULL	NULL	NULL


есть возможность условия если существует
select top 1 * from roomratesrelation where startdate <= c.tDate and c.tDate between startdate and enddate order by StartDate DESC

то один АПЛАЙ если нет то другой?
2 окт 14, 20:13    [16652649]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Да игра называется помоги себе сам((((

Хорошо, как можно улучшить вот это чудо:

DECLARE
 @iBeginDate DATE,
 @iEndDate DATE
 
SELECT    
 @iBeginDate = getdate()
,@iEndDate = Dateadd(dd, 30, getdate());
 
WITH Calendar AS (
SELECT @iBeginDate AS tDate
UNION ALL
SELECT dateadd(DAY , 1, tDate) AS tDate
FROM Calendar
WHERE dateadd (DAY, 1, tDate) <= @iEndDate
)

SELECT c.tDate
,isnull(t1.roomid, t2.roomid)
,isnull(t1.rateid, t2.rateid)
,isnull(t1.discount, t2.discount)
,isnull(t1.startdate, t2.startdate)
,isnull(t1.enddate, t2.enddate)
,isnull(t1.isactive, t2.isactive)
FROM Calendar c
OUTER APPLY (select top 1 * from roomratesrelation where startdate <= c.tDate and c.tDate between startdate and enddate order by StartDate desc) t1
OUTER APPLY (select top 1 * from roomratesrelation order by Enddate desc) t2
OPTION (MAXRECURSION 0)
3 окт 14, 13:25    [16655957]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
как можно улучшить вот это чудо:

Не писать дурацких условий

where startdate <= c.tDate and c.tDate between startdate and enddate
Если c.tDate уже between startdate and enddate, т.е. c.tDate >= startdate, то зачем нужно еще startdate <= c.tDate ?
3 окт 14, 13:32    [16656035]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Glory
YeaRmiX
как можно улучшить вот это чудо:

Не писать дурацких условий

where startdate <= c.tDate and c.tDate between startdate and enddate
Если c.tDate уже between startdate and enddate, т.е. c.tDate >= startdate, то зачем нужно еще startdate <= c.tDate ?


Ну не заметил... извините.

А что делать с перфомансом - и взамоблокировках. Там ведь просто полный атас.
3 окт 14, 13:51    [16656212]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
А что делать с перфомансом

А что с ним ?

YeaRmiX
и взамоблокировках.

Взаимоблокирвоки при SELECT ???
3 окт 14, 13:52    [16656225]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Glory
YeaRmiX
А что делать с перфомансом

А что с ним ?

YeaRmiX
и взамоблокировках.

Взаимоблокирвоки при SELECT ???


А что селект не блокирует таблицы - просто там джоинятся как мне кажется два одинаковых подзапроса и как мне кажется это не есть гуд ...
3 окт 14, 14:01    [16656300]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
А что селект не блокирует таблицы

А что блокировки и взаимоблокировки уже одно и тоже ?

YeaRmiX
просто там джоинятся как мне кажется два одинаковых подзапроса и как мне кажется это не есть гуд

Одинаковые подзапросы не состоят из разного числа символов
В чем смысл OUTER APPLY (select top 1 * from roomratesrelation order by Enddate desc) t2, который возвращает всегда одни и те же данные ?
3 окт 14, 14:05    [16656327]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Glory
YeaRmiX
А что селект не блокирует таблицы

А что блокировки и взаимоблокировки уже одно и тоже ?

YeaRmiX
просто там джоинятся как мне кажется два одинаковых подзапроса и как мне кажется это не есть гуд

Одинаковые подзапросы не состоят из разного числа символов
В чем смысл OUTER APPLY (select top 1 * from roomratesrelation order by Enddate desc) t2, который возвращает всегда одни и те же данные ?


блокировки - простая блокировка, ну написал не подумав

Смысл последнего в предоставлении дефолтных значений последней строки которая не нулл
3 окт 14, 14:10    [16656358]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
Смысл последнего в предоставлении дефолтных значений последней строки которая не нулл

И зачем одну и туже строку выбирать 100500 раз ?
3 окт 14, 14:11    [16656371]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

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

типа аля дефолт для селекта
3 окт 14, 14:21    [16656441]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
Glory,

типа аля дефолт для селекта

100500 раз убедится что это одно и тоже значение ?
1го раза недостаточно что ли ?
3 окт 14, 14:23    [16656453]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Glory,
Извините.... не могли бы более подробно разьяснить в чем суть Вашего одного раза. Просто намек не ясен, извините.

Моя суть в том что если попадется условия в Т1 то продолжится выборка актуальных значений.
3 окт 14, 14:29    [16656498]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
Извините.... не могли бы более подробно разьяснить в чем суть Вашего одного раза.

В том, что вы зачем то запихнули этот запрос в OUTER APPLY
3 окт 14, 14:32    [16656526]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Glory
YeaRmiX
Извините.... не могли бы более подробно разьяснить в чем суть Вашего одного раза.

В том, что вы зачем то запихнули этот запрос в OUTER APPLY


Не пойму вы говрите о CROSS APPLY или о джоинах(у меня не получилось связать эти таблицы)
3 окт 14, 14:45    [16656606]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
Не пойму вы говрите о CROSS APPLY или о джоинах(у меня не получилось связать эти таблицы)

Мда
DECLARE
 @iBeginDate DATE,
 @iEndDate DATE
 
SELECT    
 @iBeginDate = getdate()
,@iEndDate = Dateadd(dd, 30, getdate());
 
WITH Calendar AS (
SELECT @iBeginDate AS tDate
UNION ALL
SELECT dateadd(DAY , 1, tDate) AS tDate
FROM Calendar
WHERE dateadd (DAY, 1, tDate) <= @iEndDate
)

SELECT c.tDate
,isnull(t1.roomid, t2.roomid)
,isnull(t1.rateid, t2.rateid)
,isnull(t1.discount, t2.discount)
,isnull(t1.startdate, t2.startdate)
,isnull(t1.enddate, t2.enddate)
,isnull(t1.isactive, t2.isactive)
FROM Calendar c
OUTER APPLY (select top 1 * from roomratesrelation where c.tDate between startdate and enddate order by StartDate desc) t1
CROSS JOIN (select top 1 * from roomratesrelation order by Enddate desc) t2
OPTION (MAXRECURSION 0)


Сообщение было отредактировано: 3 окт 14, 14:48
3 окт 14, 14:48    [16656625]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
И я о том же.)))) Спасибо.
3 окт 14, 14:51    [16656643]     Ответить | Цитировать Сообщить модератору
 Re: Пройтись по краю дат выбрать день/значение(или плавающий алгоритм)  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
И я о том же.))))

CROSS APPLY - это не CROSS JOIN
Так же, как блокировки - это не взаимоблокировки.
3 окт 14, 14:57    [16656690]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить