在左连接中执行 Or 时,加载/处理永远不会结束,直到 SQL 超时

问题描述 投票:0回答:2

我有一个表格可以计算每人的数字总和。然后查看该表以获取该数字并将其添加到另一组数据中。我所做的左连接有效如果我只将其链接到一列,但它需要链接到两个可能的列,并且当我添加 或 部分以添加第二列链接时,它会处于永无止境的加载/处理直到超时。

查表sql:ENT.Sessions表

Select
    pupilonrolltableid,
    pupilnolongeronrolltableid,
    sum(sessions) As Sessions
From CensusAttendance
Where attendancereason NOT LIKE '%[/\BDJLPSVWXY#]%'
Group By pupilnolongeronrolltableid, pupilonrolltableid

我使用两列,因为两列都不会被填充,它将是其中之一,即

这是我用来构建新表数据的sql,我使用左连接从这个Sessions表中获取数据 人口普查表:

Select
             Coalesce(ONR.forename,OFR.forename) As Forename
            ,Coalesce(ONR.middlenames,OFR.middlenames) As Middlenames
            ,Coalesce(ONR.surname,OFR.surname) As Surname
            ,Coalesce(ONR.upn,OFR.upn) As UPN
            ,Coalesce(ONR.[schoolcensustableid],OFR.[schoolcensustableid]) As SchoolCensusTableID
            ,CSC.term As Term
            ,CSC.[year] As [Year]
            ,Case When TSO.Sessions IS NULL Then Cast('0.00' As Decimal(10,2)) Else TSO.Sessions END As SessionsAuthorised
            ,Case When ONR.termlysessionspossible IS NULL Then Cast('0.00' As Decimal(10,2)) Else ONR.termlysessionspossible END As SessionsPossibleOnRoll
            ,Case When OFR.termlysessionspossible IS NULL Then Cast('0.00' As Decimal(10,2)) Else OFR.termlysessionspossible END As SessionsPossibleOffRoll
            ,ONR.termlysessionseducational As TermlySessionsEducationalOnRoll
            ,OFR.termlysessionseducational As TermlySessionsEducationalOffRoll
            ,ONR.termlysessionsexceptional As TermlySessionsExceptionalOnRoll
            ,OFR.termlysessionsexceptional As TermlySessionsExceptionalOffRoll
            ,ONR.termlysessionsauthorised As TermlySessionsAuthorisedOnRoll
            ,OFR.termlysessionsauthorised As TermlySessionsAuthorisedOffRoll
            ,ONR.termlysessionsunauthorised As TermlySessionsUnauthorisedOnRoll
            ,OFR.termlysessionsunauthorised As TermlySessionsUnauthorisedOffRoll
            ,Coalesce (ONR.DateTimeInserted, OFR.DateTimeInserted) As DateTimeInserted
            ,Coalesce (ONR.DateTimeUpdated,OFR.DateTimeUpdated) As DateTimeUpdated
            ,Coalesce (ONR.MD5Checksum, OFR.MD5Checksum) As MD5Checksum
            ,Coalesce (ONR.LoadID, OFR.LoadID) As LoadID
            ,Coalesce (ONR.UniversalID, OFR.UniversalID) As UniversalID
        From STG.Census_PupilOnRoll As ONR
            Full Outer Join STG.Census_PupilNoLongerOnRoll As OFR On ONR.schoolcensustableid = OFR.schoolcensustableid And ONR.upn = OFR.upn
            Left Outer Join STG.Census_SchoolCensus As CSC On ONR.schoolcensustableid = CSC.schoolcensustableid Or OFR.schoolcensustableid = CSC.schoolcensustableid
            Left Outer Join ENT.CensusSessions As TSO On TSO.pupilnolongeronrolltableid = OFR.pupilnolongeronrolltableid Or TSO.pupilonrolltableid = ONR.pupilonrolltableid

因此,最后一个左外连接,如果我将其保留在第一个 On = 处,它将加载数据,但仅链接到会话表中的某些数据,但一旦我添加了 Or,它就永远不会加载。我不是最好的 sql 编码员,主要使用我正在工作的内容。任何人都可以帮助使其正常工作。请注意,会话和构建其他数据集的 SQL 中有超过一百万条记录。也有超过100万左右2-300万

sql sql-server t-sql left-join
2个回答
1
投票

OR
通常会给性能带来问题,因为它通常会阻止编译器使用索引查找。

在你的情况下,因为你只是由于完全连接而使用它,所以你可以尝试

ON TSO.pupilnolongeronrolltableid = ISNULL(ONR.pupilonrolltableid, OFR.pupilnolongeronrolltableid)

您还应该清理其余的代码:

  • 使用
    ISNULL
    代替
    CASE
    COALESCE
  • 不要将文字文本转换为
    decimal
    ,只需首先将其设置为小数即可。
Select
    ISNULL(ONR.forename, OFR.forename) As Forename
   ,ISNULL(ONR.middlenames, OFR.middlenames) As Middlenames
   ,ISNULL(ONR.surname, OFR.surname) As Surname
   ,ISNULL(ONR.upn, OFR.upn) As UPN
   ,ISNULL(ONR.schoolcensustableid, OFR.schoolcensustableid) As SchoolCensusTableID
   ,CSC.term As Term
   ,CSC.[year] As [Year]
   ,ISNULL(TSO.Sessions, 0.0) As SessionsAuthorised
   ,ISNULL(ONR.termlysessionspossible, 0.00) As SessionsPossibleOnRoll
   ,ISNULL(OFR.termlysessionspossible, 0.00) As SessionsPossibleOffRoll
   ,ONR.termlysessionseducational As TermlySessionsEducationalOnRoll
   ,OFR.termlysessionseducational As TermlySessionsEducationalOffRoll
   ,ONR.termlysessionsexceptional As TermlySessionsExceptionalOnRoll
   ,OFR.termlysessionsexceptional As TermlySessionsExceptionalOffRoll
   ,ONR.termlysessionsauthorised As TermlySessionsAuthorisedOnRoll
   ,OFR.termlysessionsauthorised As TermlySessionsAuthorisedOffRoll
   ,ONR.termlysessionsunauthorised As TermlySessionsUnauthorisedOnRoll
   ,OFR.termlysessionsunauthorised As TermlySessionsUnauthorisedOffRoll
   ,ISNULL(ONR.DateTimeInserted, OFR.DateTimeInserted) As DateTimeInserted
   ,ISNULL(ONR.DateTimeUpdated, OFR.DateTimeUpdated) As DateTimeUpdated
   ,ISNULL(ONR.MD5Checksum, OFR.MD5Checksum) As MD5Checksum
   ,ISNULL(ONR.LoadID, OFR.LoadID) As LoadID
   ,ISNULL(ONR.UniversalID, OFR.UniversalID) As UniversalID
From STG.Census_PupilOnRoll As ONR
Full Outer Join STG.Census_PupilNoLongerOnRoll As OFR
  On ONR.schoolcensustableid = OFR.schoolcensustableid
 And ONR.upn = OFR.upn
Left Outer Join STG.Census_SchoolCensus As CSC
  On CSC.schoolcensustableid = ISNULL(ONR.schoolcensustableid, OFR.schoolcensustableid)
Left Outer Join ENT.CensusSessions As TSO
  On TSO.pupilnolongeronrolltableid = ISNULL(ONR.pupilonrolltableid, OFR.pupilnolongeronrolltableid);

如果这两个表完全不相交,则考虑使用

UNION ALL
以及两个单独的子查询和联接。


0
投票

如果您将其构造为单独执行所有连接,您可能会拥有更好的运气:

with Census_PupilOnRoll As (
    select *
    from STG.Census_PupilOnRoll As ONR
        Left Outer Join STG.Census_SchoolCensus As CSC 
            On CSC.schoolcensustableid = ONR.schoolcensustableid
        Left Outer Join ENT.CensusSessions As TSO
            On TSO.pupilonrolltableid = ONR.pupilonrolltableid
), Census_PupilNoLongerOnRoll as (
    select
    from STG.Census_PupilNoLongerOnRoll As OFR
        Left Outer Join STG.Census_SchoolCensus As CSC
            On CSC.schoolcensustableid = OFR.schoolcensustableid
        Left Outer Join ENT.CensusSessions As TSO 
            On TSO.pupilnolongeronrolltableid = OFR.pupilnolongeronrolltableid
)
select * /* <-- your output columns go here */
from Census_PupilOnRoll As ONR
    Full Outer Join Census_PupilNoLongerOnRoll As OFR
        On ONR.schoolcensustableid = OFR.schoolcensustableid And ONR.upn = OFR.upn;
© www.soinside.com 2019 - 2024. All rights reserved.