【问题标题】:Multiple OR condition is not working in SQL join query多个 OR 条件在 SQL 连接查询中不起作用
【发布时间】:2019-09-24 05:54:02
【问题描述】:

我正在尝试从 sql 连接查询中获取数据。当我在 where 子句中使用具有 3 个组合的日期过滤器时,查询不起作用。

 IF OBJECT_ID('tempdb..#tempAllocStatus1') IS NOT NULL
                         DROP TABLE #tempAllocStatus1 

                         SELECT  Users.Name,REPLACE(Staff.Designation, 'IND ', '') as Designation, Staff.Office as Location,
                                        (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt  
                                        INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                                        WHERE ReqDt.AssignedToID = Users.UserADID AND Req.TypeOfRequest = 1 AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENRE' or ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRR' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF'))) [Indian Benchmarking Assigned], 

                                        (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt  
                                        INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                                        WHERE ReqDt.ReviewerID = Users.UserADID AND Req.TypeOfRequest = 1 AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF' or SubStatusCode='RPC' or SubStatusCode='TPRPC'))) [Indian Benchmarking Reviewer], 

                                        (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt  
                                        INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                                        WHERE ReqDt.SignoffID = Users.UserADID AND Req.TypeOfRequest = 1 AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='RPSOFF' or ReqDt.SubStatusCode='SCPC' or ReqDt.SubStatusCode='TPSCPC'))) [Indian Benchmarking Signoff],

                                        (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt  
                                        INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                                        WHERE ReqDt.AssignedToID = Users.UserADID AND Req.TypeOfRequest = 1 AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENRE' or ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRR' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF'))) + 
                                        (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt  
                                        INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                                        WHERE ReqDt.ReviewerID = Users.UserADID AND Req.TypeOfRequest = 1 AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF' or SubStatusCode='RPC' or SubStatusCode='TPRPC'))) + 
                                        (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt  
                                        INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                                        WHERE ReqDt.SignoffID = Users.UserADID AND Req.TypeOfRequest = 1 AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='RPSOFF' or ReqDt.SubStatusCode='SCPC' or ReqDt.SubStatusCode='TPSCPC'))) [Indian Benchmarking Total],


                           (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt 
                            WHERE ReqDt.AssignedToID = Users.UserADID AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENRE' or ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRR' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF'))) [All Assigned], 
                            (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt 
                            WHERE ReqDt.ReviewerID = Users.UserADID AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF' or SubStatusCode='RPC' or SubStatusCode='TPRPC'))) [All Reviewer], 
                            (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt 
                            INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                            WHERE ReqDt.SignoffID = Users.UserADID AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='RPSOFF' or ReqDt.SubStatusCode='SCPC' or ReqDt.SubStatusCode='TPSCPC'))) [All Signoff],
                            (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt 
                            WHERE ReqDt.AssignedToID = Users.UserADID AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENRE' or ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRR' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF'))) + 
                            (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt 
                            WHERE ReqDt.ReviewerID = Users.UserADID AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='BENSF' or ReqDt.SubStatusCode='DRSO' or ReqDt.SubStatusCode='RPSOFF' or SubStatusCode='RPC' or SubStatusCode='TPRPC'))) + 
                            (SELECT  COUNT(ReqDt.ID) FROM tblTPRequestDetail ReqDt 
                            INNER JOIN  tblTPRequest Req ON ReqDt.RequestID = Req.Id 
                            WHERE ReqDt.SignoffID = Users.UserADID AND ((ReqDt.StatusCode = 'COMP' or ReqDt.StatusCode = 'PCR') or (ReqDt.StatusCode = 'AWIP' and ReqDt.SubStatusCode='RPSOFF' or ReqDt.SubStatusCode='SCPC' or ReqDt.SubStatusCode='TPSCPC'))) [All Total]

                            INTO #tempAllocStatus1

                            FROM tblUserRolesMapping Users

                                LEFT JOIN [tblstaff] Staff ON Users.UserADID = Staff.AD_Id                                  
                                LEFT JOIN tblTPRequestDetail UserAssigned ON UserAssigned.AssignedToID = Users.UserADID
                                LEFT JOIN tblTPRequestDetail UserReviewer ON UserReviewer.ReviewerID = Users.UserADID
                                LEFT JOIN tblTPRequestDetail UserSignoff ON UserSignoff.SignoffID = Users.UserADID

                                LEFT JOIN tblTPRequest TPRAssigned ON UserAssigned.RequestID = TPRAssigned.ID
                                LEFT JOIN tblTPRequest TPRReviewer ON UserReviewer.RequestID = TPRReviewer.ID
                                LEFT JOIN tblTPRequest TPRSignoff ON UserSignoff.RequestID = TPRSignoff.ID 

                            WHERE Users.Active = 1 and Users.[RoleId] !=6
                                      AND TPRAssigned.crtddate >= '2017-04-01'  and TPRAssigned.crtddate<= '2017-05-30'

                                      OR TPRReviewer.crtddate >= '2017-04-01'  AND TPRReviewer.crtddate<='2017-05-30'

                                      OR TPRSignoff.crtddate >= '2017-04-01'  AND TPRSignoff.crtddate<='2017-05-30' 
                                       GROUP BY Users.UserADID,  Users.Name, Staff.Designation,Staff.Office 

                                SELECT * FROM #tempAllocStatus1 WHERE [All Total] > 0

                                    UNION ALL

                                SELECT * FROM #tempAllocStatus1 WHERE [All Total] = 0 

我在下面的查询行中遇到了问题。

                             AND TPRAssigned.crtddate >= '2017-04-01'  and TPRAssigned.crtddate<= '2017-05-30'

                                      OR TPRReviewer.crtddate >= '2017-04-01'  AND TPRReviewer.crtddate<='2017-05-30'

                                      OR TPRSignoff.crtddate >= '2017-04-01'  AND TPRSignoff.crtddate<='2017-05-30' 

如果我使用任意 2 个日期组合,它工作正常。如果我添加日期的第三个条件,它会加载很长时间并且没有得到任何数据。请帮忙。

【问题讨论】:

  • 我建议您另外问一个关于“如何简化此查询”的问题?所有这些相关的子查询将花费您大量的资源,并且可以用简单的连接和案例语句代替。
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出(包括逐字错误消息)的示例输入(作为初始化代码);标签和版本;明确的规范和解释。这包括您可以提供的最少代码,即您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)对于包含 DBMS/产品和 DDL 的 SQL,其中包括约束和索引以及表格格式的基表初始化。对于包括 EXPLAIN 结果和统计信息的 SQL 性能。 PS 显然有非最小代码。
  • 了解 LEFT JOIN ON 返回的内容:INNER JOIN ON 行 UNION ALL 不匹配的左表行,由 NULL 扩展。作为 OUTER JOIN 的一部分,始终知道您想要什么 INNER JOIN。 WHERE 或 INNER JOIN ON 在 OUTER JOIN ON 删除任何由 NULL 扩展的行后,需要右 [sic] 表列不为 NULL,即只留下 INNER JOIN ON 行,即“将 OUTER JOIN 转换为 INNER JOIN”。你有那个。 PS“不工作”告诉我们什么。 PS 既然你有一个有用的答案,请提出一个新问题。使用minimal reproducible example。 PS 速度与代码错误无关。
  • 我已经问了一个关于“如何简化查询”的单独问题。请帮我。网址是stackoverflow.com/questions/58094354/…

标签: sql sql-server tsql join


【解决方案1】:

您有操作顺序问题,因为AND 的优先级高于 OR。使用括号强加你想要的逻辑:

WHERE
    ... AND
    (TPRAssigned.crtddate BETWEEN '2017-04-01' AND '2017-05-30') OR
    (TPRReviewer.crtddate BETWEEN '2017-04-01' AND '2017-05-30') OR
    (TPRSignoff.crtddate BETWEEN '2017-04-01' AND '2017-05-30')

请注意,您当前的逻辑实际上被评估为:

(TPRAssigned.crtddate >= '2017-04-01' AND TPRAssigned.crtddate <= '2017-05-30') OR
(TPRReviewer.crtddate >= '2017-04-01' AND TPRReviewer.crtddate <= '2017-05-30') OR
(TPRSignoff.crtddate >= '2017-04-01'  AND TPRSignoff.crtddate <= '2017-05-30')

很可能,这不是您想要的逻辑。

【讨论】:

  • 我也试过这些方法。但它也加载了很长时间并且超时
  • @user3581029 您的查询性能是另一个主题,而不是您所问的。我修正了你的逻辑。
  • 我已经尝试过这些带括号的方法。无论有没有括号,这两种组合都有效。即使使用括号,第三个 OR 条件也不起作用。正如我在查询中提到的,它加载了很长时间并且没有得到任何数据
  • 您的查询量很大,我不适合提出优化建议。
  • 谢谢蒂姆。其他任何人都可以帮我解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多