【问题标题】:How to use Aggregate in Select Statement如何在 Select 语句中使用聚合
【发布时间】:2017-05-03 11:57:46
【问题描述】:

我的代码有问题,它似乎不接受我的选择查询中的聚合函数。我想用我的DATEDIFF(MONTH,MIN(LoanDateStart),MAX(LoanPaymentDue)) 实现的是我想获得总月数,然后使用月数来计算其余查询。

我收到了这个错误:

消息 130,级别 15,状态 1,第 11 行 无法对包含聚合或子查询的表达式执行聚合函数。

有没有其他方法可以实现?

查询

SELECT 
ISNULL(SUM((CAST(((((lt.InterestRate/100) * lc.LoanAmount) +
 lc.LoanAmount) / ((dbo.fnNumberOfYears(CONVERT(VARCHAR(15), LoanDateStart, 
101), CONVERT(VARCHAR(15), LoanPaymentDue, 101)) * DATEDIFF(MONTH, 
MIN(LoanDateStart),  MAX(LoanPaymentDue)))  * 2)) AS DECIMAL(18,2)))),0)
FROM LoanContract lc 
INNER JOIN LoanType lt ON lt.LoanTypeID = lc.LoanTypeID 
WHERE lc.LoanTypeID = 1 AND lc.EmployeeID = 5

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    请尝试以下...

    SELECT ISNULL( SUM( ( CAST( ( ( ( ( lt.InterestRate / 100 ) *
                                      LoanContract.LoanAmount ) +
                                    LoanContract.LoanAmount ) /
                                  ( ( dbo.fnNumberOfYears( CONVERT( VARCHAR( 15 ),
                                                                    LoanDateStart,
                                                                    101 ),
                                                           CONVERT( VARCHAR( 15 ),
                                                                    LoanPaymentDue,
                                                                    101 ) ) *
                                      monthsDifference ) *
                                    2 ) ) AS DECIMAL( 18,
                                                      2 ) ) ) ),
                   0 )
    FROM ( SELECT LoanContractID AS LoanContractID,
                  DATEDIFF( MONTH,
                            MIN( LoanDateStart ),
                            MAX( LoanPaymentDue ) ) AS monthsDifference
           FROM LoanContract
           GROUP BY LoanContractID
         ) AS monthsDifferenceFinder
    INNER JOIN LoanContract ON LoanContract.LoanContractID = monthsDifferenceFinder.LoanContractID
    INNER JOIN LoanType lt ON lt.LoanTypeID = LoanContract.LoanTypeID
    WHERE lc.LoanTypeID = 1
      AND lc.EmployeeID = 5
    

    请注意,我使用 LoanContractID 代替了 LoanContract 的主键,因为您没有说明那是什么。

    问题的原因是 SUM()(聚合函数)对 MIN()MAX() 的结果进行运算,它们本身就是聚合函数。这很困惑SQL-Server

    我已经通过编写一个子查询来解决这个问题,该子查询根据 LoanContract 的唯一标识符而不是每条记录的主键来确定每个 LoanContract 的两个值之间的差异。 (您的数据是 3NF(第三范式)吗?)

    然后基于LoanContractID 将子查询的结果连接到LoanContract,有效地将每个LoanContractmonthsDifference 值附加到该LoanContract 的每条记录中。

    SUM() 然后能够处理检索到的值,而不必尝试聚合正确聚合的值。

    如果您有任何问题或cmets,请随时发表相应的评论。

    【讨论】:

    • 在答案中添加了说明。
    • 感谢您的精彩解释,我现在完全明白为什么了。非常感谢@toonice
    【解决方案2】:

    无论如何,我现在解决了这个问题,我正在使用LEFT OUTER JOIN

    这是我的代码:

    SELECT
    ISNULL(SUM((CAST(((((lt.InterestRate/100) * lc.LoanAmount) + lc.LoanAmount) / ((dbo.fnNumberOfYears(CONVERT(VARCHAR(15), LoanDateStart, 101), CONVERT(VARCHAR(15), LoanPaymentDue, 101)) * x.NumberOfMonths)  * 2)) AS DECIMAL(18,2)))),0)
    FROM LoanContract lc 
    INNER JOIN LoanType lt ON lt.LoanTypeID = lc.LoanTypeID
    LEFT OUTER JOIN(SELECT
    lc.LoanTypeID AS 'LoanTypeID',
    lc.EmployeeID AS 'EmployeeID', 
    (DATEDIFF(MONTH, MIN(LoanDateStart),  MAX(LoanPaymentDue))) AS 'NumberOfMonths'
    FROM LoanContract lc 
    INNER JOIN LoanType lt ON lt.LoanTypeID = lc.LoanTypeID
    GROUP BY lc.EmployeeID, lc.LoanTypeID) x ON x.EmployeeID = lc.EmployeeID AND x.LoanTypeID = lc.LoanTypeID 
    WHERE lc.LoanTypeID = 1 AND lc.EmployeeID = 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-07
      • 2014-04-05
      • 2013-06-17
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多