Oracle:聚合连接分组结果中未分组列的方法
我有一个包含多个聚合函数和几个分组列的查询。我想从组中取出一个分组列,并对它拥有的所有 VARCHAR 值执行某种聚合“连接”。 (最好是在新的回车分隔列表中)。
这是我的查询,我记下我想在哪里执行此操作:
SELECT rownum, F.*
FROM (SELECT
c.logical_type "MerchantType",
c.merchant_id "MerchantID",
c.m_name "MerchantName",
m.m_name "TransferredBy", /* <----- Make this aggregate */
SUM(DECODE(b.ba_price,null,0,DECODE(b.BILL_SRVC_ID,'CREDITCHANGE',0,b.ba_price))) "TotalValue",
sum(DECODE(b.ba_price,null,0,DECODE(b.BILL_SRVC_ID,'CREDITCHANGE',b.ba_price,0))) "LimitChange",
SUM(DECODE(b.ba_status,'bdone',1,0)) "TxnCount",
sum(to_number(decode(substr(b.ba_merchant_freetext,1,10),'Commission',substr(b.ba_merchant_freetext, 12,(instr(b.ba_merchant_freetext,';',1,1)-12))))) "Commission"
FROM bill_auth0 b,
merchant0 m,
merchant0 c
WHERE
b.srvc_prod_id = 'TRANSFER'
AND b.ba_channel = 'WPSS'
AND b.ba_status IN ('bdone')
AND b.merchant_id = m.merchant_id
AND b.customer_id = c.merchant_id
AND b.ba_timestamp BETWEEN to_date( '11/01/2009', 'MM/DD/YYYY' )
AND to_date( '11/17/2009', 'MM/DD/YYYY' )+1
GROUP BY
c.logical_type,
c.merchant_id,
c.m_name,
m.m_name /* <-- Remove from Grouped By */
ORDER BY c.logical_type, c.merchant_id, m.m_name) F;
所以本质上我希望能够得到一个结果,其中“TransferredBy”看起来像这样: 商户1
商家2
则为 Merchant3 。
如果有 3 个单独的 m.m_name 与该组行匹配,
I have a query with several aggregate functions and then a few grouped columns. I want to take one of the grouped columns out of the group and perform some sort of aggregate "concatenating" of all the VARCHAR values it has. (Ideally in a new carriage separated list).
Here is my query and I note where I'd like to do this:
SELECT rownum, F.*
FROM (SELECT
c.logical_type "MerchantType",
c.merchant_id "MerchantID",
c.m_name "MerchantName",
m.m_name "TransferredBy", /* <----- Make this aggregate */
SUM(DECODE(b.ba_price,null,0,DECODE(b.BILL_SRVC_ID,'CREDITCHANGE',0,b.ba_price))) "TotalValue",
sum(DECODE(b.ba_price,null,0,DECODE(b.BILL_SRVC_ID,'CREDITCHANGE',b.ba_price,0))) "LimitChange",
SUM(DECODE(b.ba_status,'bdone',1,0)) "TxnCount",
sum(to_number(decode(substr(b.ba_merchant_freetext,1,10),'Commission',substr(b.ba_merchant_freetext, 12,(instr(b.ba_merchant_freetext,';',1,1)-12))))) "Commission"
FROM bill_auth0 b,
merchant0 m,
merchant0 c
WHERE
b.srvc_prod_id = 'TRANSFER'
AND b.ba_channel = 'WPSS'
AND b.ba_status IN ('bdone')
AND b.merchant_id = m.merchant_id
AND b.customer_id = c.merchant_id
AND b.ba_timestamp BETWEEN to_date( '11/01/2009', 'MM/DD/YYYY' )
AND to_date( '11/17/2009', 'MM/DD/YYYY' )+1
GROUP BY
c.logical_type,
c.merchant_id,
c.m_name,
m.m_name /* <-- Remove from Grouped By */
ORDER BY c.logical_type, c.merchant_id, m.m_name) F;
So essentially I want to be able to have a result where "TransferredBy" would look something like:
Merchant1
Merchant2
Merchant3
if there were 3 seperate m.m_name matches to this Group Row.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一篇关于不同字符串聚合技术的好文章。
我可以添加另一种方法(基于 XML):
在 11g Release 2 中,我们终于内置了 LISTAGG 函数。
Here is a nice article about different string aggregation techniques.
I can add yet another method (XML-based):
And in 11g Release 2 we finally have built-in LISTAGG function.
虽然我不知道有任何内置函数能够解决您的问题,但似乎 您可以编写自己的聚合函数,可以!因为我很好奇,所以我尝试实现一个自定义聚合函数,该函数将文本与分隔符连接起来:
类型规范:
类型正文:
聚合函数:
毕竟,我能够执行以下查询:
结果是单行:
Although I do not know of any built-in function capable of solving your problem, it appears that you can write your own aggregate function that can! Because I was curious, I tried my hand at implementing a custom, aggregate function that concatenates text with a delimiter:
The type spec:
The type body:
The aggregate function:
After all this, I was able to execute the following query:
The result was a single row:
使用 listagg http://download.oracle.com/docs /cd/E14072_01/server.112/e10592/functions087.htm
它有充分的记录和支持。
use listagg http://download.oracle.com/docs/cd/E14072_01/server.112/e10592/functions087.htm
It is well documented and supported.
尝试
wm_concat(yourColumn)
...它是否可用取决于您的数据库版本。它不是官方记录的函数,但与上面列出的许多其他函数执行相同的操作。这将生成一个逗号分隔的列表。要获得新行字符,您可以用 replace() 将其包围起来。
另一个技巧是在 wm_concat() 中使用 unique,例如 wm_concat(distinct yourColumn),这样您就不会不会得到重复项。
Try out
wm_concat(yourColumn)
... it is available depending on your db version. It is not an officially documented function, but does the same thing as many of the other functions listed above.This makes a comma separated list. To get the new line character you can surround it with replace()
Another tip is to use distinct within the wm_concat() such as wm_concat(distinct yourColumn) so that you don't get duplicates.