SQL需要两个WHERE子句条件

时间:2014-03-25 20:38:02

标签: sql-server tsql

我需要一个基于表字段值的条件Where子句或Case语句。

这就是我所拥有的而且它不起作用:

Select n.id, n.message, n.Type
From Notifications n
Where
(
      n.Type = 1 
      And ApplicationMask & isnull(@applicationMask,2147483647)<> 0
      And Cast(GETDATE() as Date) Between Cast(StartDate AS Date) and
                                             Cast(EndDate as Date) 
      And Not Exists(Select notificationID 
                     From NotificationDelivery nd 
                     Where nd.NotificationID = n.id 
                     and nd.UserID = @userID)

 )
 OR
 (
      n.Type = 2 
      And ApplicationMask & ISNULL(@applicationMask,2147483647) <> 0
      And Cast(GETDATE() as Date) Between Cast(StartDate AS Date) and 
                                           Cast(EndDate as Date)      
 )

我认为OR搞砸了。顶部Where子句本身就可以工作,但是像这样它返回的行不应该返回。似乎NOT EXIST部分被忽略了。有没有更好的办法?我在SQL查询方面不太强大。

4 个答案:

答案 0 :(得分:1)

尝试此操作以获得更好的性能和更好的可读性。我认为这将返回您需要的结果:

set @applicationMask = isnull(@applicationMask,1)

Select n.id, n.message, n.Type
From Notifications n
Where
Type in (1,2) 
And ApplicationMask = 1
And @applicationMask > 0
And dateadd(d, 0, datediff(d, -1, GETDATE()) > StartDate
And dateadd(d, 0, datediff(d, 0, GETDATE())) <= EndDate
And (type = 2 or Not Exists(Select null 
                From NotificationDelivery nd 
                Where nd.NotificationID = n.id 
                and nd.UserID = @userID))

答案 1 :(得分:0)

完全未经测试但是如何构建SQL如下:

Select n.id, n.message, n.Type
  From Notifications n
 Where 1=1
   And (ApplicationMask & ISNULL(@applicationMask,2147483647) <> 0
   And Cast(GETDATE() as Date) Between Cast(StartDate AS Date) 
   And Cast(EndDate as Date))     
    OR (ApplicationMask & isnull(@applicationMask,2147483647)<> 0 
   And Cast(GETDATE() as Date) Between Cast(StartDate AS Date) 
   And Cast(EndDate as Date) 
   And Not Exists(Select notificationID 
                    From NotificationDelivery nd 
                   Where nd.NotificationID = n.id 
                     and nd.UserID = @userID))

只是一个想法......祝你好运。

答案 2 :(得分:0)

我建议只将两个条件分成两个查询,将UNION分成结果

SELECT  n.id, n.message, n.Type
FROM    Notifications n
WHERE   n.Type = 1
    AND ApplicationMask & isnull(@applicationMask,2147483647)<> 0
    AND Cast(GETDATE() as Date) Between Cast(StartDate AS Date) and
                                     Cast(EndDate as Date) 
    AND Not Exists(Select notificationID 
             From NotificationDelivery nd 
             Where nd.NotificationID = n.id 
             and nd.UserID = @userID)

UNION

SELECT  n.id, n.message, n.Type
FROM    Notifications n
WHERE   n.Type = 2 
    AND ApplicationMask & ISNULL(@applicationMask,2147483647) <> 0
    AND Cast(GETDATE() as Date) Between Cast(StartDate AS Date) and 
                                       Cast(EndDate as Date)      

答案 3 :(得分:0)

我会尝试缩小数据集的范围并过滤类似于

的内容
Select
 n.id, n.message, n.Type
From (select n.id, n.message, n.Type
    from Notifications
    WHERE
    n.Type in (1, 2 )
    And ApplicationMask & ISNULL(@applicationMask,2147483647) <> 0
        And Cast(GETDATE() as Date) Between Cast(StartDate AS Date) and 
                                           Cast(EndDate as Date) 
    ) n

Where  not (n.Type =1 
        And Not Exists(Select notificationID 
                     From NotificationDelivery nd 
                     Where nd.NotificationID = n.id 
                     and nd.UserID = @userID)
        )