2013-11-26 22 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表獲取所有ID,ValidFrom和ValidTo

  • 的指定日期範圍之間從SpecialOffers排除任何記錄,如果日(例如星期二)在SpecialOfferExcludedDays用於指定ID的存在。它不限於1天。例如,一個ID可以被排除在週一和週六

我的查詢看起來像此刻,沒有邏輯的天

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

下列因此,例如,我正在做一個訂單今天預訂酒店,在2013年12月1日晚上。給我所有可能的特別優惠,有效期爲12月1日。考慮到某些日子無效的任何特別優惠

編輯

一個樣本交易可能會得到所有的Id,其中住宿是12月1日至12月25日(星期五和星期六除外)。

這可能嗎?或者我會更好地在我的C#應用​​程序中編寫這個邏輯。

+0

你能給一些更多的數據和預期的結果? –

+0

我已經添加了一些額外的數據 – Tommassiov

+1

@ Tommo1977爲什麼要存儲每週的一天?這絕對可以從你的約會中提取。沒有? –

回答

0

我認爲這是你要找的。這將爲您提供表1中符合datefrom和兩個條件的所有行,除了與表3中的星期二記錄相關聯的任何行(通過table2 many-many join)。

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#代替,沒有人能夠回答,對於你不知道更多關於你的應用程序的結構和數據集的大小(在其他項目中)。

編輯:這裏是一個答案,我相信這是你想要什麼更新的版本,知道什麼優惠適用於任何一天:

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

我看到你澄清了你的問題。所以你想知道任何給定的日期,有什麼特別優惠可用?試圖回答的困惑是你的查詢有一個日期硬編碼的範圍,而不是一個日期。如果這是一天,我會這樣做: 'DECLARE @dateIwanttocheck datetime ='1/1/2013'SELECT Id FROM Specialoffer t1 WHERE @dateIwanttocheck ValidFrom和ValidTo之間並且不存在(從SpecialOfferExcludedDays t2選擇1內連接天t3上t2.DayID = t3.dayID其中t1.ID = t2.ID和日期部分(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多次停電天。否則在這種情況下你會得到多個ID。

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

相關問題