【问题标题】:Time out error sql when joined table is empty连接表为空时超时错误sql
【发布时间】:2021-03-10 00:55:42
【问题描述】:

我被以下 WITH 部分所困扰。当 startdate 和 enddate 条件不满足时没有结果时,查询需要很长时间并最终返回超时错误。当有符合周期的记录时,结果是正常的,没有错误。

    ILY as (
        select 
        A.[EANcode] as 'EAN',
        FL.[ContractId] as 'FacContractId',
        SUM(case when FL.[Tp] = 'Dal' AND FL.[LijnType] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'Dal_Statement',
        SUM(case when FL.[Tp] = 'Dal' AND FL.[Lt] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'Dal_Account',
        SUM(case when FL.[Tp] = 'Dal' AND FL.[Lt] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'Dal_InvoicedAccount',
        SUM(case when FL.[Tp] = 'Piek' AND FL.[Lt] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'Piek_Statement',
        SUM(case when FL.[Tp] = 'Piek' AND FL.[Lt] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'Piek_Account',
        SUM(case when FL.[Tp] = 'Piek' AND FL.[Lt] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'Piek_InvoicedAccount',
        SUM(case when FL.[Tp] = 'Enkel' AND FL.[Lt] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'Enkel_Statement',
        SUM(case when FL.[Tp] = 'Enkel' AND FL.[Lt] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'Enkel_Account',
        SUM(case when FL.[Tp] = 'Enkel' AND FL.[Lt] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'Enkel_InvoicedAccount',
        SUM(case when FL.[Tp] = 'TL Dal' AND FL.[Lt] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'TLDal_Statement',
        SUM(case when FL.[Tp] = 'TL Dal' AND FL.[Lt] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'TLDal_Account',
        SUM(case when FL.[Tp] = 'TL Dal' AND FL.[Lt] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'TLDal_InvoicedAccount',
        SUM(case when FL.[Tp] = 'TL Piek' AND FL.[Lt] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'TLPiek_Statement',
        SUM(case when FL.[Tp] = 'TL Piek' AND FL.[Lt] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'TLPiek_Account',
        SUM(case when FL.[Tp] = 'TL Piek' AND FL.[Lt] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'TLPiek_InvoicedAccount'
    
        from {FactuurLijn} FL
        inner join {Factuur} FAC on FAC.[Id] = FL.[FactuurId]
        inner join {FactuurContract} FC on FC.[FactuurId] = FAC.[Id]
        inner join {Aansluiting} A on A.[Id] = FC.[AansluitingId]
        inner join {PriceComponent} PC on PC.[Id] = FL.[PrijscomponentId]
        where A.[EANcode] in (select getContracts.[EANCode] from getContracts)
        and FC.[ContractId] in (select getContracts.[ContractId] from getContracts where getContracts.[ContractNummer]  <> '')
        and (FL.[StartDate] >= @StartDate and FL.[EndDate] <=@EndDate)
        and PC.[PriceType] = 'VP'
        and PC.[PriceComp] = 'Levering'
        and FAC.[Show] = 1
        and FL.[ContractId] <> 0
        group by A.[EANcode], FL.[ContractId], FL.[Tp], FL.[Lt]
    )

select .....

我已将联接更改为左联接,并将 sum 子句更改为 ISNULL(SUM(...),0) 但这没有任何效果。 (我更改了一些列名以提高这篇文章的可读性)。

【问题讨论】:

    标签: jquery sql join timeout


    【解决方案1】:

    如果这是一个边缘情况,您可以使用IF 来处理它:

    IF EXISTS
    (
        SELECT 1 
        FROM {FactuurLijn}
        WHERE (FL.[StartDate] >= @StartDate and FL.[EndDate] <=@EndDate)
    )
    

    如果为真,则执行您的正常查询,这很快,否则返回空结果集或消息。

    或者,您可以尝试在另一个 CTE 或表中过滤高级行。像这样的:

    ILY_Filtered AS
    (
        SELECT [FactuurId]
        FROM {FactuurLijn}
        WHERE (FL.[StartDate] >= @StartDate and FL.[EndDate] <=@EndDate)
            and FL.[ContractId] <> 0
    )
    

    然后在您的查询中,您将拥有:

    from ILY_Filtered FLF
    INNER JOIN {FactuurLijn} FL
       ON ELF.[FactuurId] = FL.[FactuurId]
    

    但我更喜欢将此结果存储在表中(变量或临时或您的 RDMS 提供的其他东西)。

    【讨论】:

    • 感谢您提出的解决方案。问题是如果我只检查日期,我会错过其他过滤器,这也可能导致空结果(目前我只知道日期不匹配时的空结果),我还必须检查 eancodes 和 contractIds 是否是在我之前创建的 getcontracts 表中。所以这意味着如果我需要先检查是否有结果,我将不得不运行更大的查询。这不会矫枉过正吗?首先运行查询以检查是否有结果,然后再次执行查询(但使用总和)..
    【解决方案2】:

    我已将查询更改为:

    InvoicesCheck as (
    SELECT 
      FL.[FactuurId],
      CASE WHEN EXISTS (select {FactuurLijn}.[Id]
            from {FactuurLijn} FL
                inner join {Factuur} FAC on FAC.[Id] = FL.[FactuurId]
                inner join {FactuurContract} FC on FC.[FactuurId] = FAC.[Id]
                inner join {Aansluiting} A on A.[Id] = FC.[AansluitingId]
                inner join {PrijsComponent} PC on PC.[Id] = FL.[PrijscomponentId]
                where A.[EANcode] in (select getContracts.[EANCode] from getContracts)
                and FC.[ContractId] in (select getContracts.[ContractId] from getContracts)
                and (FL.[StartDatumFactuurLijnDetail] >= @StartDate and FL.[EindDatumFactuurLijnDetail] <=@EndDate)
                and PC.[PrijsType] = 'VP'
                and PC.[PrijsComponentType] = 'Levering'
                and FAC.[Tonen] = 1)
           then 'TRUE' 
           else 'FALSE'
      end as 'Found'  
    FROM {FactuurLijn}
    ),
    InvoicesLastYear as (
        select
        A.[EANcode] as 'EAN',
        FL.[ContractId] as 'FacContractId',
        case when InvoicesCheck.[Found] = 'TRUE'
        then    
        SUM(case when FL.[Tariefperiode] = 'Dal' AND FL.[LijnType] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'Dal_Statement',
        SUM(case when FL.[Tariefperiode] = 'Dal' AND FL.[LijnType] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'Dal_Account',
        SUM(case when FL.[Tariefperiode] = 'Dal' AND FL.[LijnType] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'Dal_InvoicedAccount',
        SUM(case when FL.[Tariefperiode] = 'Piek' AND FL.[LijnType] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'Piek_Statement',
        SUM(case when FL.[Tariefperiode] = 'Piek' AND FL.[LijnType] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'Piek_Account',
        SUM(case when FL.[Tariefperiode] = 'Piek' AND FL.[LijnType] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'Piek_InvoicedAccount',
        SUM(case when FL.[Tariefperiode] = 'Enkel' AND FL.[LijnType] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'Enkel_Statement',
        SUM(case when FL.[Tariefperiode] = 'Enkel' AND FL.[LijnType] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'Enkel_Account',
        SUM(case when FL.[Tariefperiode] = 'Enkel' AND FL.[LijnType] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'Enkel_InvoicedAccount',
        SUM(case when FL.[Tariefperiode] = 'TL Dal' AND FL.[LijnType] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'TLDal_Statement',
        SUM(case when FL.[Tariefperiode] = 'TL Dal' AND FL.[LijnType] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'TLDal_Account',
        SUM(case when FL.[Tariefperiode] = 'TL Dal' AND FL.[LijnType] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'TLDal_InvoicedAccount',
        SUM(case when FL.[Tariefperiode] = 'TL Piek' AND FL.[LijnType] = 'Statement' then FL.[Hoeveelheid] else 0 end) as 'TLPiek_Statement',
        SUM(case when FL.[Tariefperiode] = 'TL Piek' AND FL.[LijnType] = 'Account' then FL.[Hoeveelheid] else 0 end) as 'TLPiek_Account',
        SUM(case when FL.[Tariefperiode] = 'TL Piek' AND FL.[LijnType] = 'InvoicedAccount' then FL.[Hoeveelheid] else 0 end) as 'TLPiek_InvoicedAccount'
        else 
            0 as 'Dal_Statement',
            0 as 'Dal_Account',
            0 as 'Dal_InvoicedAccount',
            0 as 'Piek_Statement',
            0 as 'Piek_Account',
            0 as 'Piek_InvoicedAccount',
            0 as 'Enkel_Statement',
            0 as 'Enkel_Account',
            0 as 'Enkel_InvoicedAccount',
            0 as 'TLDal_Statement',
            0 as 'TLDal_Account',
            0 as 'TLDal_InvoicedAccount',
            0 as 'TLPiek_Statement',
            0 as 'TLPiek_Account',
            0 as 'TLPiek_InvoicedAccount'
            end
        from {FactuurLijn} FL
        inner join {Factuur} FAC on FAC.[Id] = FL.[FactuurId]
        inner join {FactuurContract} FC on FC.[FactuurId] = FAC.[Id]
        inner join {Aansluiting} A on A.[Id] = FC.[AansluitingId]
        inner join {PrijsComponent} PC on PC.[Id] = FL.[PrijscomponentId]
        where A.[EANcode] in (select getContracts.[EANCode] from getContracts)
        and FL.[ContractId] in (select getContracts.[ContractId] from getContracts)
        and (FL.[StartDatumFactuurLijnDetail] >= @StartDate and FL.[EindDatumFactuurLijnDetail] <=@EndDate)
        and PC.[PrijsType] = 'VP'
        and PC.[PrijsComponentType] = 'Levering'
        and FAC.[Tonen] = 1
        group by A.[EANcode], FL.[ContractId]
        )
    

    但是,我收到的消息是“as”和“and”附近的语法不正确。 我们可以在 WITH 子句中执行 EXISTS 吗?

    【讨论】:

      猜你喜欢
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 2013-03-30
      • 2017-07-12
      相关资源
      最近更新 更多