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

问题描述:

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

当mode = 6时,我想说的是 拉下列日期范围列表之间的所有列,并且其中一列pmt_rcvd_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)

分组例如,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总结所有T他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分组)

+0

你能给我们预期的产出使用你给我们的样品吗?另外请注意,“这些不同的值在每行中都是相同的”,在数据库中这不是一件好事。想象一下,您想要在一条记录中更改pmt_rcvd_amt,您需要在所有其他记录中更改它。 – 2015-01-20 22:23:10

+0

如果您知道a.pmt_rcvd_amt的值对于每一行都始终是相同的,则可以使用任意聚合函数(如min或max)来获取“some”值。这样做的“正确”方法是创建一个包含汇总数据的派生表,另一个派生表包含您将其与之比较的单例值。虽然有很多次它完全不受你的控制,但我同意@LuisAlves的说法,这听起来像是糟糕的数据库设计。 – Xedni 2015-01-20 22:25:46

+0

在WHERE子句中使用子查询。因此,a.pmt_rcvd_amt (某些查询为客户检索SUM) – 2015-01-20 22:26:03

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] 

如果该字段是不在组中的,它必须是一个聚合函数,如SUM/MAX等..如果按客户编号上面的查询应该工作。然后,只需用MAX( - )将选择语句中的字段包装起来,因为MAX也可以与char字段一起使用。

+0

问题是,我希望查询单独返回字段换句话说,我需要三条线返回customer_no 74500386和我需要独特的元素--10,219和50分开,所以我不能在选择语句中将它们最大化。换句话说,我需要查询返回所有的唯一行,其中一个字段的总和不计算另一个的值,但我仍然需要查看字段的所有部分。 – YelizavetaYR 2015-01-20 22:36:40

+0

你可以按字段分组吗? – 2015-01-20 22:41:10

+0

不,我只是想测试它们的总和(按customer_no分组)是否相等,如果不相等则返回那些不同的行。 – YelizavetaYR 2015-01-20 22:42:18

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)) 
+0

当我尝试此选项时,出现以下错误:列'LV_CHC_TOURS_RSV_DATA.id_key'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。 id_key是我查询中的另一列。 – YelizavetaYR 2015-01-20 22:30:40

+0

所以你说我拉的查询是 - customer_no和过滤日期范围/和聚合在内部选择? – YelizavetaYR 2015-01-20 22:43:10

+0

内部查询仅返回满足要求的不同'customer_no'。它们被主查询使用 – rtruszk 2015-01-20 22:51:35

如果我理解正确,首先您需要为每位客户总结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 

我严重过度简化您的查询,当然。

+0

我不需要总结他们的输出 - 我需要总结他们做比较 - 其中sli_due_amt的总和不等于pmt_rcvd_amt - 但我希望输出设置为唯一的单个列。 – YelizavetaYR 2015-01-20 22:59:40