我有一个看起来像这样的表:
ID YEAR
1 2001
1 2002
1 2003
1 2004
1 2005
1 2006
1 2007
1 2008
2 1995
2 1996
2 1997
2 1998
然后我尝试的查询:
select "ID", count("Year") "Count", listagg("Year", ', ') within group (order by "Year") "Years"
from (
select distinct tbl2.id "ID", tbl1.year "Year"
from table1 tbl1 join table2 tbl2
on(tbl1.tbl2id = tbl2.id)
)
group by "ID"
得到了这样的结果:
ID Count Years
1 8 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
2 4 1995, 1996, 1997, 1998
但我想要的是将结果限制为3,但显示剩余的结果如下:
ID Count Years
1 3 2001, 2002, 2003
1 3 2004, 2005, 2006
1 2 2007, 2008
2 3 1995, 1996, 1997
2 1 1998
答案 0 :(得分:3)
另一种方式可能是
WITH table_x AS
(
SELECT 1 ID, 2001 YEAR FROM DUAL UNION ALL
SELECT 1, 2002 FROM DUAL UNION ALL
SELECT 1 , 2003 FROM DUAL UNION ALL
SELECT 1 , 2004 FROM DUAL UNION ALL
SELECT 1 , 2005 FROM DUAL UNION ALL
SELECT 1 , 2006 FROM DUAL UNION ALL
SELECT 1 , 2007 FROM DUAL UNION ALL
SELECT 1 ,2008 FROM DUAL UNION ALL
SELECT 2 ,1995 FROM DUAL UNION ALL
SELECT 2 ,1996 FROM DUAL UNION ALL
SELECT 2 ,1997 FROM DUAL UNION ALL
SELECT 2 ,1998 FROM DUAL
)
,p as (
select id,year,mod(rownum,3) md ,rownum
from table_x tbl1
order by year
)
,q as
(Select row_number() over (partition by id,md order by year ,id asc) rown,p.id,year
from P order by id,year
)
select ID, count(Year) Count, listagg(Year, ', ') within group (order by Year) Years
from q
group by id,rown;
O / P:
1 3 2001, 2002, 2003
1 3 2004, 2005, 2006
1 2 2007, 2008
2 3 1995, 1996, 1997
2 1 1998
答案 1 :(得分:3)
我只想添加一个row_number()
并将其用于聚合:
select id, count(*) as cnt,
listagg(year, ', ') within group (order by year) as years
from (select tbl2.id, tbl1.year,
row_number() over (partition by tbl2.id order by tbl1.year asc) as seqnum
from table1 tbl1 join
table2 tbl2
on tbl1.tbl2id = tbl2.id
group by tbl2.id, tbl1.year
)
group by id, floor( (seqnum - 1) / 3 ) ;
Here是一个显示逻辑的rextester。
答案 2 :(得分:3)
使用ceil
功能:
select "ID", count("Year") "Count",
listagg("Year", ', ') within group (order by "Year") "Years"
from (
select tbl2.id "ID", tbl1.year "Year",
row_number() over ( partition by tbl2.id order by tbl1.year ) rn
from table1 tbl1 join table2 tbl2
on(tbl1.tbl2id = tbl2.id)
)
group by "ID", ceil(rn/3);
答案 3 :(得分:2)
解决问题的方法:
CREATE OR REPLACE VIEW Tble_rnum AS
SELECT
Table1.*,
row_number() OVER (PARTITION BY ID ORDER BY YEAR) as rn
FROM Table1;
CREATE OR REPLACE VIEW tbl2 AS (
SELECT *
FROM Tble_rnum
MODEL
PARTITION BY (ID)
DIMENSION BY (rn)
MEASURES (YEAR, LENGTHB(Year) len, 0 cum_len)
RULES (
cum_len[1] = LEN[1] + LENGTH(', '),
cum_len[rn > 1] = CASE WHEN cum_len[cv()-1] + LEN[cv()] + LENGTHB(', ') <= 20
THEN cum_len[cv()-1] + LEN[cv()] + LENGTHB(', ')
ELSE LEN[cv()] + LENGTH(', ')
END));
CREATE OR REPLACE VIEW tbl3 AS (
SELECT *
FROM tbl2
MODEL
PARTITION BY (ID)
DIMENSION BY (rn)
MEASURES (YEAR, len, cum_len, 0 sub_id)
RULES (
sub_id[1] = 1,
sub_id[rn > 1] = CASE WHEN cum_len[cv()] = len[cv()] + LENGTHB(', ')
THEN sub_id[cv() - 1] + 1
ELSE sub_id[cv() - 1]
END));
SELECT
ID,
COUNT(YEAR) AS Counts,
LISTAGG(Year, ', ') WITHIN GROUP (ORDER BY YEAR) AS YEARS
FROM tbl3
group by ID, sub_id;
<强>输出:强>
ID COUNTS YEARS
1 3 2001, 2002, 2003
1 3 2004, 2005, 2006
1 2 2007, 2008
2 3 1995, 1996, 1997
2 1 1998
如需演示,请按照以下链接: