错误将一列的总和分组为另一列的一般值

时间:2015-01-20 22:13:23

标签: mysql sql join having

我有一个参数列表,第一个是日期范围@start_dt和@end_dt我的一个字段是模式。如果mode = 1,则查询以单向运行,如果模式 - 2,另一个等,我有7个可能的版本。

当mode = 6时,我想说的是 拉下下面的日期范围列表和一列pmt_rcvd_amt不等于sli_paid_amt之和的所有列。现在我希望sli_paid_amt按customer_no分组     Where a.create_dt between @start_dt and @end_dt     and a.pmt_rcvd_amt <> sum(a.sli_paid_amt)

例如:

customer_no sli_due_amt pmt_rcvd_amt`
85244305    200.00  200.00
74500386    50.00   219.00
74500386    219.00  219.00
74500386    10.00   219.00
86119821    NULL    NULL

我希望它为customer_no 74500386进行分组(将所有sli_due_amt加起来)所以219 + 50. + 10因此279然后将它与pmt_rcvd_amt列中的219进行比较。 (这些值将是相同的)

我的代码看起来像这样......

select distinct 
        a.id_key ,
        a.customer_no ,
        a.customer_prefix ,
        a.customer_lname 
        ... 
        a.current_child_price ,
        a.current_other_price 
        from LV_CHC_TOURS_RSV_DATA a
        left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
        left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
        Where a.create_dt between @start_dt and @end_dt 
        and a.pmt_rcvd_amt <> sum(a.sli_paid_amt)

Error Message: An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.

然后我将其更改为尝试在我的代码中使用:

from LV_CHC_TOURS_RSV_DATA a
        left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
        left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
        Where a.create_dt between @start_dt and @end_dt 
        group by a.customer_no
        having sum(a.sli_paid_amt) <> a.pmt_rcvd_amt

现在我收到以下错误消息:

Column 'LV_CHC_TOURS_RSV_DATA.pmt_rcvd_amt' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.

我知道它有点奇怪 - 但我希望给定的customer_no能够汇总所有sli_due_amts,然后看看它们是否等于pmt_rcvd_amt的不同值。因为这些不同的值在每一行中都是相同的。

我想要的输出是什么:

customer_no sli_due_amt pmt_rcvd_amt`
74500386    50.00   219.00
74500386    219.00  219.00
74500386    10.00   219.00

因为:50 + 219 + 10不等于219(按客户74500386分组)

3 个答案:

答案 0 :(得分:1)

SELECT a.customer_no, SUM(a.sli_paid_amt), MAX(a.pmt_rcvd_amt) AS [Payment Amount], MAX(some_other_field), ...
 from LV_CHC_TOURS_RSV_DATA a
        left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
        left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
        Where a.create_dt between @start_dt and @end_dt 
        group by a.customer_no
        having sum(a.sli_paid_amt) <> [Payment Amount]

如果该字段不在group by中,则它必须是汇总函数,例如SUM / MAX等...如果按客户ID分组,则上述查询应该有效。然后用MAX( - )包装select语句中的字段,因为MAX也可以与char字段一起使用。

答案 1 :(得分:0)

HAVING子句中,您只能使用聚合函数。 a.pmt_rcvd_amt每行都相同,因此您可以使用min(a.pmt_rcvd_amt)max(a.pmt_rcvd_amt)
在下面的代码中,子查询返回满足您要求的所有客户的数量。然后,主查询使用它们来选择所有需要的行。

所以试试这个:

select 
    a.id_key ,
    a.customer_no ,
    a.customer_prefix ,
    a.customer_lname 
    ... 
    a.current_child_price ,
    a.current_other_price 
from LV_CHC_TOURS_RSV_DATA a 
    left outer join LT_CHC_TOURS_RSV_LANG b on a.language = b.id 
    left outer join LV_CHC_TOURS_RSV_CS c on a.add_text = c.source_no 
where a.customer_no in 
( select a1.customer_no from LV_CHC_TOURS_RSV_DATA a1       
    Where a1.create_dt between @start_dt and @end_dt 
    group by a1.customer_no
    having sum(a1.sli_paid_amt) <> min(a1.pmt_rcvd_amt))

答案 2 :(得分:0)

如果我理解正确,首先你需要为每个客户总结sli_due_amt,然后你想要返回各行,不包括有pmt_rcvd_amt =总和sli_due_amt的客户。

所以:

WITH Summed as
(select
customer_no,
sum(sli_due_amt) as sli_sum
from LV_CHC_TOURS_RSV_DATA...
GROUP BY cust_no
)

    select *
    from
    LV_CHC_TOURS_RSV_DATA t1
    inner join summed
      on t1.customer_no = summed.customer_no
      and t1.pmt_rcvd_amt <> sli_sum

当然,我过度简化了你的查询。