我有以下表格
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'
我正在尝试编写一个查询来实现以下目标;
从ValidOrom和ValidTo的给定日期范围
如果给定Id的SpecialOfferExcludedDays中存在一天(例如星期二),则从SpecialOffers中排除任何记录。它不限于1天。例如,可以在星期一和星期六排除ID
我的查询目前看起来类似于以下内容,没有日期的逻辑
SELECT Id
FROM SpecialOffers
WHERE (ValidFrom > '2013-11-25'
AND ValidTo < '2013-11-30')
例如,我今天就2013年12月1日晚的酒店预订订单。给我所有可能的特价优惠,有效期为12月1日。考虑到任何特别优惠。在某些日子无效
修改
样品交易可能会在12月1日至12月25日期间(不包括周五和周六)之间获得所有ID。
这可能吗?或者我会更好地在我的C#app中编写这个逻辑。
答案 0 :(得分:1)
我认为这就是你要找的东西。这将为您提供表1中符合日期的所有行和两个条件,除了与表3中的星期二记录相关联的任何行(通过table2多次连接)。
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)
答案 1 :(得分: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;
我在这里添加了“distinct”,以防万一SpecialOfferExcludedDays对同一SpecialOffer有多个停电天数。否则,在这种情况下你会获得多个ID。
根据反馈,我想你可能只想要一个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;