如果与另一个表中的条目(如假日日期)匹配,则排除记录的SQL查询
我有两张桌子: 应用程序如果与另一个表中的条目(如假日日期)匹配,则排除记录的SQL查询,sql,join,sql-server-2005,Sql,Join,Sql Server 2005,我有两张桌子: 应用程序 应用程序ID(int) 应用程序名称(varchar) I可用(位) 及 假日 应用程序ID(int) holidaydate(日期时间) 我需要为任何给定的applicationname获取isavailable标志,但它只应在当天不是假日时返回。isavailable标志独立于节假日-它仅在系统范围内出现问题时设置,而不是在设定的时间表上设置 我最初的想法是: select top 1 apps.isavailable from dbo.Applications a
应用程序ID(int)
应用程序名称(varchar)
I可用(位) 及 假日
应用程序ID(int)
holidaydate(日期时间) 我需要为任何给定的applicationname获取isavailable标志,但它只应在当天不是假日时返回。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上,因此没有日期类型,因此我必须转换它)
但是,即使今天是假日,它也在恢复记录。如果今天不是假日,如何使用“notin”或“except”子句(或其他内容)构造此查询以仅返回记录
更新
我不需要所有没有假期的applicationname的列表-我需要指定apps.applicationname的记录。下面的答案只返回今天没有假期的应用程序名称。如果不是假日,则查询应返回isavailable标志,否则如果是假日,则不返回任何记录。我不关心其他的应用程序
另外,如果我添加一个表,如:
操作小时数应用程序ID(int)
周一开放(日期时间)
周一关闭(日期时间)
星期二开放日(日期时间)
周二关闭(日期时间)
//一周七天的营业时间和营业时间 如果记录在给定日期的小时内且不是假日,我是否可以加入这三个表,只返回记录?我必须在单独的查询中执行此操作吗?您可以使用“WHERE NOT EXISTS”:
我在那里进行转换是为了将getdate()调用截短为日期。我还没有测试过这个精确的查询,但我认为它可以为您完成这项工作。执行以下操作:
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)
)
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
当然,如果使用SQLServer2008的“日期”数据类型,或者您可以将日、月、年分别存储在“假日”中,则会更简单、更快
Marc以下查询将为您提供当前日期未定义假日的应用程序列表
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)
)
基本上,我们所做的就是选择所有不匹配的地方。好的,只是为了不同,像这样的东西怎么样:
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)
)
SELECT a.isAvailable
FROM Application a
WHERE NOT EXISTS (
SELECT TOP 1 0
FROM Holidays b
WHERE a.applicationid = b.applicationid
AND holidaydate = $today
)
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是唯一的,您将始终得到一行,其中联接的右半部分为null,除非当前日期与假日匹配,在这种情况下,查询将不返回任何结果
我不知道它与其他解决方案在性能方面的表现如何;我相信连接通常应该比子查询快,但这可能取决于各种因素,所以YMMV。这个呢:
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这将提供所有未定义假日的应用程序,但我只需要指定apps.applicationname的isavailable标志。我不想在查询之后遍历列表。另外,如果我必须在另一个表上加入,我不能合并where和where not子句,只需添加一个附加子句。apps.AppName='您的应用程序'。您可以添加任何需要的连接,我更新了示例,向您展示了如何通过应用程序名称进行限制,假设参数@appname有效-谢谢。你能把它编辑成包含一个以上的结尾部分,这样就有人可以剪切粘贴它了吗?太好了!(我不知道它在开始的时候去了哪里!)这和Michael Sellers的回答有相同的问题-这给出了所有没有定义假期的应用程序,但是我只需要指定apps.applicationname.Sorry的isavailable标志-我认为这不会有问题,因为您的原始查询已经包含了对applicationname=@appname的测试。我想你知道怎么做。马特——在大多数情况下,表演都差不多。看起来这个用户只需要一个应用程序,所以子查询路径可能会快一点…Mitchel Sellers-我一直认为子查询的问题是每行都会重复,但我明白你的意思。我对绩效真正了解的是,如果在特定情况下绩效很重要,我应该对其进行衡量“不存在的地方”的方法在任何情况下都更具可读性。