取出分组后前 N 名对应记录
【问题】
SQL “group by” question - I can’t select every column
I have a database where each row has an id, a URL, and an XML. The IDs are unique, but URLs column can have duplicates. I need all the URLs, without duplicates, and for each URL I need the id and XML.
If I ask only for the URL and the Id, I use the following query:
selectURL, max(ID) asID fromT1 groupby URL
And all is working great.
But when I want also the XML, and I use the following query:
selectURL, max(ID) asID, XMLfromT1 groupby URL
I get the following error:
ISC ERROR CODE:335544569
ISC ERROR MESSAGE:
Dynamic SQL Error
SQL error code = -104
user name required
What am I doing wrong?
Thanks,
Dikla
Thanks for the answers. I want to add an explanation:
In case of duplicate URLs, I don’t care which of them will be returned. But I need to get them without duplicates, even if the XML is different between the rows. Is it possible?
Thanks!
别人的回答:
selectid, url, xml
from table1
whereid in (
select min(id)
from table1
groupby url)
selecturlMaxId.id, urlMaxId.url, table1.html from (selecturl, max(id) id fromtable1 groupbyurl) urlMaxId innerjointable1 on urlMaxId.id = table1.id
【回答】
这个问题的难点是 max 函数只能计算出最大值 / 最小值,但不能取出“最大值对应的记录”,再加上分组和关联,就会让问题更显复杂。在 ORACLE 中还可以使用 keep/ top/row_number,或者用窗口函数等方法,当然,这些方法都比较麻烦。 如果数量不是非常大,这种情况建议采用集算器。集算器的 top 函数可以取出最大值对应的记录,比如 salary.top(amount;3) 取出 amount 最小的三条记录,salary.top(-amount;1) 取出 amount 最大的那条记录。下面的这句代码可以解决你的所有问题:
A |
|
1 |
=T1.group(URL).(~.top(1;ID)).conj() |
简单解释一下。
T1: T1 表
.group(URL): 按 URL 对 T1 分组
.(~.top(1;ID)): 继续计算,对每组数据,取出 ID 最小的记录。
.conj(): 将各组数据合并。
集算器是结构化计算开发工具,和 JAVA 或报表工具很容易集成,可以参考:【Java 如何调用 SPL 脚本】