检查DAYOFWEEK()是否存在于日期范围之间

时间:2013-11-26 13:30:35

标签: mysql sql

我有以下表格

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的给定日期范围

  • 之间获取SpecialOffers表中的所有ID
  • 如果给定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中编写这个逻辑。

2 个答案:

答案 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。

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