我有两张桌子:
应用
applicationid(int)
applicationname(varchar)
isavailable(bit)
和
假日
applicationid(int)
holidaydate(datetime)
我需要获取任何给定应用程序名称的 isavailable 标志,但只有当day不是假日时它才会返回。 isavailable 标志与假期无关 - 仅在存在系统范围问题时才设置,而不是在设定的时间表上设置。
我最初有类似的东西:
select top 1 apps.isavailable
from dbo.Applications apps, dbo.Holidays hol
where apps.applicationid = hol.applicationid and
apps.applicationname = @appname and
((datediff(dd,getdate(),hol.holidaydate)) != 0)
但即使今天是假期,这也是回归记录,因为其他假日日期今天不相等。
我试过
and (CONVERT(VARCHAR,getdate(),101)) not in (CONVERT(VARCHAR,hol.holidaydate,101))
(它在SQL Server 2005上,所以没有Date类型所以我必须转换它)
但是,即使今天是假期,也会返回记录。如果今天不是假日,我如何使用“not in”或“except”子句(或其他内容)构造此查询以仅返回记录?
更新
我不需要没有假期的所有应用程序名称列表 - 我需要指定apps.applicationname的记录。以下答案仅返回今天没有假期的应用程序名称。如果查询不是假日,则查询应返回isavailable标志,否则如果是假日则不返回任何记录。我不关心其他应用程序。
另外,如果我添加了一个表格如下:
HoursOfOperations
applicationid(int)
星期一(datetime)
mondayclose(datetime)
tuesdayopen(datetime)
tuesdayclose(datetime)
//打开和关闭一周中的所有七天
我是否可以加入所有这三个表格,只有在指定日期的几小时内且不是假期时才返回记录?我是否必须在单独的查询中执行此操作?
答案 0 :(得分:15)
以下查询应该会为您提供一份没有为CURRENT日期定义假期的应用程序列表。
SELECT apps.ApplicationName, apps.isavailable
FROM dbo.Applications apps
WHERE apps.ApplicationName = @AppName
AND NOT EXISTS
( SELECT *
FROM Holidays
WHERE ApplicationId = apps.ApplicationId
AND CONVERT(VARCHAR,getdate(),101) = CONVERT(VARCHAR,holidaydate,101)
)
基本上我们所做的就是选择没有匹配的所有内容。
答案 1 :(得分:5)
好的,只是为了与众不同,这样的事情怎么样:
select apps.isavailable
from dbo.Application apps left outer join dbo.Holidays hol
on apps.applicationid = hol.applicationid
and convert(varchar(10),getdate(),101) = convert(varchar(10),hol.holidaydate,101)
where apps.applicationname = @appname
and hol.applicationid is null
基本上,您根据applicationid和当前日期加入表。由于它是左连接,因此您将始终获得与@appname匹配的所有应用程序,然后您只需根据假日日期作为当前日期筛选出任何匹配的结果。假设applicationname是唯一的,除非当前日期与假日匹配,否则您将始终获得单行,其中右半部分为空,在这种情况下查询将不返回任何结果。
我不知道它与其他解决方案在性能方面如何叠加;我认为连接通常比子查询更快,但这可能取决于各种因素,所以YMMV。
答案 2 :(得分:4)
您可以使用“WHERE NOT EXISTS”:
SELECT *
FROM Applications a
WHERE NOT EXISTS (
SELECT *
FROM Holidays h
WHERE h.ApplicationID = a.ApplicationID
AND HolidayDate = cast(cast(getdate() as int) as datetime)
)
我正在那里进行强制转换,将getdate()调用截断为日期。没有测试过那个确切的查询,但我认为它会为你完成这项工作。
答案 3 :(得分:2)
做这样的事情:
SELECT (fields) FROM Application
WHERE NOT EXISTS
(SELECT * FROM Holidays
WHERE ApplicationID = Application.ApplicationID
AND DAY(getdate()) = DAY(holidaydate)
AND MONTH(getdate()) = MONTH(holidaydate)
AND YEAR(getdate()) = YEAR(holidaydate)
)
当然,使用SQL Server 2008的“DATE”数据类型会更容易,更快,或者如果您可以分别在“假期”中存储日,月,年。
马克
答案 4 :(得分:2)
SELECT a.isAvailable
FROM Application a
WHERE NOT EXISTS (
SELECT TOP 1 0
FROM Holidays b
WHERE a.applicationid = b.applicationid
AND holidaydate = $today
)
答案 5 :(得分:0)
这个怎么样:
SELECT
Application.isavailable
FROM
Holidays
RIGHT JOIN
Application
ON
Holidays.applicationid = Application.applicationid
WHERE
((Application.applicationname='app1') AND
(((Holidays.holidaydate=CurrentDate()) AND (Holidays.applicationid Is Null)) OR
(holidays.holidaydate Is Null)));
“'app1'”应由系统特定函数替换为变量说明符和“CurrentDate()”以返回当前日期。
干杯
/ A