首页 文章

SQL查询如果匹配另一个表中的条目(例如假日日期),则排除记录

提问于
浏览
8

我有两张 table :

应用程序applicationid(int)applicationname(varchar)是可用的(位)

假期applicationid(int)holidaydate(datetime)

我需要获取任何给定应用程序名称的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上,所以没有Date类型所以我必须转换它)

但同样,即使今天是假期,它也会返回记录 . 如果今天不是假日,我如何使用“not in”或“except”子句(或其他内容)来构造此查询,以仅返回记录?

Update

我不需要没有假期的所有应用程序名称列表 - 我需要指定apps.applicationname的记录 . 以下答案仅返回今天没有假期的应用程序名称 . 如果查询不是假日,则查询应返回isavailable标志,否则如果是假日则不返回任何记录 . 我不关心其他应用程序 .

另外,如果我添加一个表格如下:

HoursOfOperations applicationid(int)mondayopen(datetime)mondayclose(datetime)tuesdayopen(datetime)tuesdayclose(datetime)//打开和关闭一周的所有七天

我是否可以加入所有这三个表格,只有在特定日期的小时内且不是假期时才返回记录?我是否必须在单独的查询中执行此操作?

6 回答

  • 15

    好吧,只是为了与众不同,这样的事情怎么样:

    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

    做这样的事情:

    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”数据类型会更容易,更快,或者如果您可以分别在“假期”中存储日,月,年 .

  • 5

    以下查询应该为您提供一个没有为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)
    )
    

    基本上我们所做的就是选择没有匹配的所有东西 .

  • 4
    SELECT a.isAvailable
      FROM Application a
     WHERE NOT EXISTS (
        SELECT TOP 1 0
          FROM Holidays b
         WHERE a.applicationid = b.applicationid
           AND holidaydate = $today
     )
    
  • 0

    您可以使用“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()调用截断为日期 . 没有测试过那个确切的查询,但我认为它会为你完成这项工作 .

  • 2

    这个如何:

    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()”替换,以返回当前日期 .

    干杯

    /一个

相关问题