2013-11-26 6 views
0

я следующие таблицыПроверьте DAYOFWEEK() существует между диапазоном дат

Specialoffer 
Id (int) 
ValidFrom (date) 
ValidTo (date) 

SpecialOfferExcludedDays 
Id (int) (ForeignKey with Table1.Id) 
DayId (int) 

Days 
DayId (int) (ForeignKey with Table3.DayId) 
Name (text) 

Specialoffer содержит

'1', '2013-01-01', '2013-01-14' 

'2', '2013-02-01', '2013-02-05' 

'3', '2013-11-21', '2013-11-25' 

SpecialOfferExcludedDays содержит

'3', '4' 

Дни содержит

'1', 'Sunday' 
'2', 'Monday' 
'3', 'Tuesday' 
'4', 'Wednesday' 
'5', 'Thursday' 
'6', 'Friday' 
'7', 'Saturday' 

Я пытаюсь написать запрос для достижения следующего;

  • Получить все Идентификаторы из таблицы SpecialOffers между заданной датой диапазоном ValidFrom и ValidTo

  • Исключить любые записи из SpecialOffers, если существует день (например вторник) в SpecialOfferExcludedDays для данного идентификатора. Это не ограничивается одним днем. Например, идентификатор может быть исключен в понедельник и субботу

Мой запрос выглядит примерно так на данный момент без каких-либо логики для дней

SELECT Id 
FROM SpecialOffers 
WHERE (ValidFrom > '2013-11-25' 
AND ValidTo < '2013-11-30') 

Так, например, я делаю заказ сегодня для бронирования гостиницы, в ночь на 1 декабря 2013 года. Дайте мне все возможные специальные предложения, которые действительны для 1 декабря. Принимая во внимание любые специальные предложения, которые недействительны в определенные дни

EDIT

Образец сделки может получить все удостоверения личности, где пребывание находится между 1 декабря и 25 декабря, за исключением пятниц и суббот.

Это можно сделать? Или я лучше буду писать эту логику в своем приложении C#.

+0

Не могли бы вы дать некоторые дополнительные данные и ваши ожидаемые результаты? –

+0

Я добавил некоторые дополнительные данные – Tommassiov

+1

@ Tommo1977 зачем хранить день недели? Это определенно можно извлечь из вашей даты. Нет? –

ответ

0

Я думаю, что это то, что вы ищете. Это даст вам все строки в таблице 1, которые соответствуют вашей дате и двум критериям, за исключением строк, связанных с записью вторника в таблице 3 (через многое соединение join2).

SELECT Id 
FROM Table1 t1 
WHERE (ValidFrom > '2013-11-25' 
AND ValidTo < '2013-11-30') 
and not exists 
(select 1 from table2 t2 
inner join table3 t3 on t2.DayID=t3.dayID 
where t1.ID=t2.ID and t3.Name='Tuesday') 

Что касается того, чтобы сделать это в C# вместо этого, никто не может ответить, что для вас, не зная больше о структуре вашего приложения и размера наборов данных (среди других предметов).

EDIT: вот ответ на то, что я считаю, это обновленная версию того, что вы хотите, зная, что предложения доступны для любого дня:

DECLARE @dateIwanttocheck datetime='1/1/2013' 
SELECT Id FROM Specialoffer t1 
WHERE @dateIwanttocheck between ValidFrom and ValidTo 
and not exists (select 1 from SpecialOfferExcludedDays t2 
inner join Days t3 on t2.DayID=t3.dayID 
where t1.ID=t2.ID and datepart(dw,@dateIwanttocheck)=t3.DayID) 
+0

Я добавил больше контекста к вопросу. – Tommassiov

+0

Извините, я добавил к вопросу, чтобы отразить пребывание в отеле. Я должен был включить это изначально. – Tommassiov

+0

Вижу, вы уточнили свой вопрос. Итак, вы хотите знать, для каких дат, какие специальные предложения доступны? Что сбивает с толку в попытке ответить, так это то, что в вашем запросе есть RANGE даты hardcode, а не одна дата. Если это один день, я бы сделал это: 'DECLARE @dateIwanttocheck datetime = '1/1/2013' SELECT Id FROM Specialoffer t1 WHERE @dateIwanttocheck между ValidFrom и ValidTo и не существует (выберите 1 из SpecialOfferExcludedDays t2 inner join Дни t3 на t2.DayID = t3.dayID где t1.ID = t2.ID и datepart (dw, @ dateIwanttocheck) = t3.DayID) ' – EGP

0

Я думаю, что это будет делать то, что вы ищете :

Используя ваши данные, вы выбираете специальное предложение 3, потому что вы ищете четверг, и предложение действительно по четвергам.

SELECT distinct so.Id 
FROM SpecialOffer so 
LEFT JOIN SpecialOfferExcludeDays soed on so.id = soed.id and soed.dayId in (5) 
WHERE ValidFrom > '2013-11-20' 
AND ValidTo < '2013-11-30' 
AND soed.id is null; 

Используя ваши данные, это не специальное предложение 3, потому что вы ищете среду, и предложение не действует по средам.

SELECT distinct so.Id 
FROM SpecialOffer so 
LEFT JOIN SpecialOfferExcludeDays soed on so.id = soed.id and soed.dayId in (4) 
WHERE ValidFrom > '2013-11-20' 
AND ValidTo < '2013-11-30' 
AND soed.id is null; 

Я добавил «отчетливый» здесь, только в случае, если SpecialOfferExcludedDays имеет несколько затемненные дней для того же SpecialOffer. В противном случае вы получите несколько идентификаторов в этом случае.

Link to SQL Fiddle

С обратной связи, я думаю, что, может быть, вы просто хотите GROUP_CONCAT, который бы перечислить все исключенные дни. Затем вы можете использовать приложение для изменения отображения. Например:

SELECT so.Id, group_concat(days.name) as excludedDayNames, 
    group_concat(days.dayId) as excludedDayIds 
FROM SpecialOffer so 
LEFT JOIN SpecialOfferExcludeDays soed on so.id = soed.id 
LEFT JOIN days on soed.dayId = days.dayId 
WHERE ValidFrom > '2013-11-20' 
AND ValidTo < '2013-11-30' 
group by so.id; 

Link to SQL Fiddle

+0

Вместо жесткого кода часть soed.dayId в (5), я хотел бы иметь возможность сделать эту проверку на все дни между диапазоном дат 2013-11-20 и 2013 -11-30 – Tommassiov

Смежные вопросы