繁体   English   中英

SQL 服务器中的条件交叉申请

[英]Conditional CROSS APPLY in SQL Server

我有以下查询,它工作得很好:

版本 #1

SELECT 
    t.ScheduleId,t.BaseDate,t.AfterDate,  
    fn.ScheduleDate AS NextBillingDate
INTO 
    #Distinct_BillableMemberAgreementItems
FROM 
    Distinct_BillableMemberAgreementItems_CTE t
CROSS APPLY 
    dbo.fn_ScheduleCalculator(t.ScheduleId, t.BaseDate, t.AfterDate, 0, 1, NULL, NULL, NULL) fn

此外,我对上述查询进行了以下更改,这些更改也可以正常工作:

版本 #2

SELECT 
    t.ScheduleId, t.BaseDate, t.AfterDate, t.memberagreementitemid,  
    fn.ScheduleDate AS NextBillingDate
INTO 
    #Distinct_BillableMemberAgreementItems
FROM 
    Distinct_BillableMemberAgreementItems_CTE t
CROSS APPLY 
    dbo.fn_ScheduleCalculator(t.ScheduleId, t.BaseDate, COALESCE(t.PreviousBillingDate, t.BaseDate), 0, 2, NULL, NULL, NULL) fn
WHERE
    fn.RowNumber = 2

问题

现在,基于某种条件,我想在用户定义的 function dbo.fn_ScheduleCalculator中传递不同的参数,但我无法正确使用语法。

这是我想要实现的目标:

SELECT 
    t.ScheduleId, t.BaseDate, t.AfterDate, t.memberagreementitemid,  
    fn.ScheduleDate AS NextBillingDate
INTO 
    #Distinct_BillableMemberAgreementItems
FROM 
    Distinct_BillableMemberAgreementItems_CTE t
CROSS APPLY
IF ((COALESCE(t.PreviousBillingDate, t.LastInvoicedDate) = GETDATE()) 
    OR (t.BaseDate <> GETDATE() and t.FromBilling = 0))

    dbo.fn_ScheduleCalculator(t.ScheduleId, t.BaseDate, COALESCE(t.PreviousBillingDate, t.BaseDate), 0, 2, NULL, NULL, NULL) fn
    WHERE
        fn.RowNumber = 2
ELSE
    dbo.fn_ScheduleCalculator(t.ScheduleId, t.BaseDate, t.AfterDate, 0, 1, NULL, NULL, NULL) fn)

我知道,如果不共享上述表格的一些数据,很难就如何实现我正在寻找的内容提出确切的语法建议,但即使有人可以建议我如何实现我正在寻找的内容,或者如果有任何问题您看到并可以指出的语法将有很大帮助。

这里:

dbo.fn_ScheduleCalculator :是用户定义的 function

Distinct_BillableMemberAgreementItems_CTE :是一个 CTE

随着对要求的澄清,您需要使用两个查询和 UNION ALL 将这两个查询合并在一起。 按照当前的要求,它将是这样的。

SELECT t.ScheduleId
    , t.BaseDate
    , t.AfterDate
    , t.memberagreementitemid
    , fn.ScheduleDate AS NextBillingDate
INTO #Distinct_BillableMemberAgreementItems
FROM Distinct_BillableMemberAgreementItems_CTE t
CROSS APPLY dbo.fn_ScheduleCalculator(t.ScheduleId, t.BaseDate, COALESCE(t.PreviousBillingDate, t.BaseDate), 0, 2, NULL, NULL, NULL) fn
where 
(
    COALESCE(t.PreviousBillingDate, t.LastInvoicedDate) = GETDATE()
    OR 
    (
        t.BaseDate <> GETDATE() 
        and 
        t.FromBilling = 0
    )
)
AND fn.RowNumber = 2

UNION ALL

SELECT t.ScheduleId
    , t.BaseDate
    , t.AfterDate
    , t.memberagreementitemid
    , fn.ScheduleDate AS NextBillingDate
INTO #Distinct_BillableMemberAgreementItems
FROM Distinct_BillableMemberAgreementItems_CTE t
CROSS APPLY dbo.fn_ScheduleCalculator(t.ScheduleId, t.BaseDate, t.AfterDate, 0, 1, NULL, NULL, NULL) fn
where NOT
(
    COALESCE(t.PreviousBillingDate, t.LastInvoicedDate) = GETDATE()
    OR 
    (
        t.BaseDate <> GETDATE() 
        and 
        t.FromBilling = 0
    )
)

您可以使用带有虚拟表的CROSS APPLY进行一些计算,然后将这些计算传递给 function。

我不知道计算的含义,所以我只是给了它们通用名称。 我也不知道你的逻辑是否正确,我只是复制了你所展示的内容。

SELECT 
    t.ScheduleId,
    t.BaseDate,
    t.AfterDate,
    t.memberagreementitemid,  
    fn.ScheduleDate AS NextBillingDate
INTO 
    #Distinct_BillableMemberAgreementItems
FROM 
    Distinct_BillableMemberAgreementItems_CTE t

CROSS APPLY (
    SELECT
        CASE WHEN ISNULL(t.PreviousBillingDate, t.LastInvoicedDate) = GETDATE()
               OR (t.BaseDate <> GETDATE() AND t.FromBilling = 0)
          THEN ISNULL(t.PreviousBillingDate, t.BaseDate)
          ELSE t.AfterDate
        END,
        CASE WHEN ISNULL(t.PreviousBillingDate, t.LastInvoicedDate) = GETDATE()
               OR (t.BaseDate <> GETDATE() AND t.FromBilling = 0)
          THEN 2
          ELSE 1
        END
) v1(SomeCalculation1, SomeCalculation2)

CROSS APPLY dbo.fn_ScheduleCalculator(
    t.ScheduleId,
    t.BaseDate,
    v.SomeCalculation1,
    0,
    v.SomeCalculation2,
    NULL, NULL, NULL
  ) fn
WHERE
    (v1.SomeCalculation2 = 1 OR fn.RowNumber = 2);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM