将一列的总和分组到另一列的一般值的错误
我有一个参数列表,第一个是日期范围@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分组)
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字段一起使用。
问题是,我希望查询单独返回字段换句话说,我需要三条线返回customer_no 74500386和我需要独特的元素--10,219和50分开,所以我不能在选择语句中将它们最大化。换句话说,我需要查询返回所有的唯一行,其中一个字段的总和不计算另一个的值,但我仍然需要查看字段的所有部分。 – YelizavetaYR 2015-01-20 22:36:40
你可以按字段分组吗? – 2015-01-20 22:41:10
不,我只是想测试它们的总和(按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))
当我尝试此选项时,出现以下错误:列'LV_CHC_TOURS_RSV_DATA.id_key'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。 id_key是我查询中的另一列。 – YelizavetaYR 2015-01-20 22:30:40
所以你说我拉的查询是 - customer_no和过滤日期范围/和聚合在内部选择? – YelizavetaYR 2015-01-20 22:43:10
内部查询仅返回满足要求的不同'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
我严重过度简化您的查询,当然。
我不需要总结他们的输出 - 我需要总结他们做比较 - 其中sli_due_amt的总和不等于pmt_rcvd_amt - 但我希望输出设置为唯一的单个列。 – YelizavetaYR 2015-01-20 22:59:40
你能给我们预期的产出使用你给我们的样品吗?另外请注意,“这些不同的值在每行中都是相同的”,在数据库中这不是一件好事。想象一下,您想要在一条记录中更改pmt_rcvd_amt,您需要在所有其他记录中更改它。 – 2015-01-20 22:23:10
如果您知道a.pmt_rcvd_amt的值对于每一行都始终是相同的,则可以使用任意聚合函数(如min或max)来获取“some”值。这样做的“正确”方法是创建一个包含汇总数据的派生表,另一个派生表包含您将其与之比较的单例值。虽然有很多次它完全不受你的控制,但我同意@LuisAlves的说法,这听起来像是糟糕的数据库设计。 – Xedni 2015-01-20 22:25:46
在WHERE子句中使用子查询。因此,a.pmt_rcvd_amt (某些查询为客户检索SUM) – 2015-01-20 22:26:03