子查询返回的值超过1。

时间:2017-08-14 08:41:10

标签: sql sql-server sql-server-2016

如果两个日期(MaturityDate,PaymentDate)之间的差异大于1个月,我想要一个会返回1的语句。 到期日是客户应付款的截止日期。

我试过了:

CASE WHEN DATEDIFF(MONTH, 
            (SELECT Date FROM dim.RepaymentSchedule rs JOIN dim.Calendar cal ON cal.DateID = rs.MaturityDateID), 
            (SELECT Date FROM dim.RepaymentSchedule rs JOIN dim.Calendar cal ON cal.DateID = rs.PaymentDateID)) 
                BETWEEN 1 AND 2 THEN 1 ELSE 0 END AS OneMonthDelay

类似于

CASE WHEN DATEDIFF(MONTH, 2017-06-30, 2017-08-01) BETWEEN 1 AND 2 THEN 1 ELSE 0 END AS OneMonthDelay

,不幸地回来了

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,<,< =,>,> =或当子查询用作   表达。

任何帮助都将不胜感激。

编辑:整个查询

SELECT
    pt.ProductType
    ,sr.SalesRegionName
    ,ca.CreditAdvisorID
    ,cal.CalendarYearMonth
    ,CASE WHEN DATEDIFF(MONTH, 
        (SELECT Date FROM dim.RepaymentSchedule rs JOIN dim.Calendar cal ON cal.DateID = rs.MaturityDateID), 
        (SELECT Date FROM dim.RepaymentSchedule rs JOIN dim.Calendar cal ON cal.DateID = rs.PaymentDateID)) 
            BETWEEN 1 AND 2 THEN 1 ELSE 0 END AS OneMonthDelay -- >1 <2 not =>1 =<2
    ,CASE WHEN DATEDIFF(MONTH, 
        (SELECT Date FROM dim.RepaymentSchedule rs JOIN dim.Calendar cal ON cal.DateID = rs.MaturityDateID), 
        (SELECT Date FROM dim.RepaymentSchedule rs JOIN dim.Calendar cal ON cal.DateID = rs.PaymentDateID))
            BETWEEN 2 AND 3 THEN 1 ELSE 0 END AS TwoMonthsDelay
    ,RANK() OVER (PARTITION BY c.ApplicationID ORDER BY rs.RepaymentNumber, rs.Amount) AS RankID
INTO #Frauds
FROM    
    dim.Contract c
    JOIN dim.Application a          ON c.ApplicationID = a.ApplicationID
    JOIN dim.Calendar cal           ON a.ApplicationDateID = cal.DateId 
    JOIN dim.CreditAdvisor ca       ON a.OriginalCreditAdvisorID = ca.CreditAdvisorId   
    JOIN dim.SalesRegion sr         ON ca.SalesRegionID = sr.SalesRegionId  
    JOIN dim.ProductType pt         ON a.ProductTypeID  = pt.ProductTypeID  
    JOIN dim.RepaymentSchedule rs   ON  c.ContractID = rs.ContractID
WHERE
    ((cal.CalendarYear >= @YearId) AND (rs.MaturityDateID < @DateId)) -- Since given year to this date
    AND ((rs.PaymentDateID = 19000101) OR (rs.PaymentDateID > rs.MaturityDateID))
    AND rs.Amount   <> 0

2 个答案:

答案 0 :(得分:0)

您是否可以尝试删除案例陈述中的联接,而是加入Calender表以及下面的所有其他表格?

SELECT
    pt.ProductType
    ,sr.SalesRegionName
    ,ca.CreditAdvisorID
    ,cal.CalendarYearMonth
    ,CASE WHEN DATEDIFF(MONTH, 
       cal.DATE,
        cal1.DATE)
            BETWEEN 1 AND 2 THEN 1 ELSE 0 END AS OneMonthDelay -- >1 <2 not =>1 =<2
    ,CASE WHEN DATEDIFF(MONTH, 
       CASE WHEN DATEDIFF(MONTH, 
       cal.DATE,
        cal1.DATE)
            BETWEEN 2 AND 3 THEN 1 ELSE 0 END AS TwoMonthsDelay
    ,RANK() OVER (PARTITION BY c.ApplicationID ORDER BY rs.RepaymentNumber, rs.Amount) AS RankID
INTO #Frauds
FROM    
    dim.Contract c
    JOIN dim.Application a          ON c.ApplicationID = a.ApplicationID
    JOIN dim.Calendar cal           ON a.ApplicationDateID = cal.DateId 
    JOIN dim.CreditAdvisor ca       ON a.OriginalCreditAdvisorID = ca.CreditAdvisorId   
    JOIN dim.SalesRegion sr         ON ca.SalesRegionID = sr.SalesRegionId  
    JOIN dim.ProductType pt         ON a.ProductTypeID  = pt.ProductTypeID  
    JOIN dim.RepaymentSchedule rs   ON  c.ContractID = rs.ContractID
    JOIN dim.Calender cal1 ON rs.MaturityDateID = cal1.DATEID
    JOIN dim.Calender cal2 ON rs.PaymentDateID = cal2.DATEID
WHERE
    ((cal.CalendarYear >= @YearId) AND (rs.MaturityDateID < @DateId)) -- Since given year to this date
    AND ((rs.PaymentDateID = 19000101) OR (rs.PaymentDateID > rs.MaturityDateID))
    AND rs.Amount   <> 0

答案 1 :(得分:0)

尽管将日历表放在FROM似乎最有意义,但问题是子查询中rs表的重复。你可以尝试:

,CASE WHEN DATEDIFF(MONTH, 
    (SELECT Date FROM dim.Calendar cal WHERE cal.DateID = rs.MaturityDateID), 
    (SELECT Date FROM dim.Calendar cal WHERE cal.DateID = rs.PaymentDateID)) 
        BETWEEN 1 AND 2 THEN 1 ELSE 0 END AS OneMonthDelay -- >1 <2 not =>1 =<2
,CASE WHEN DATEDIFF(MONTH, 
    (SELECT Date FROM dim.Calendar cal WHERE cal.DateID = rs.MaturityDateID), 
    (SELECT Date FROM dim.Calendar cal WHERE cal.DateID = rs.PaymentDateID))
        BETWEEN 2 AND 3 THEN 1 ELSE 0 END AS TwoMonthsDelay