create temp table tmp_apps (
id integer
);
create temp table tmp_pos (
tmp_apps_id integer,
position integer
);
insert into tmp_apps
select 1 id union
select 2 id
;
insert into tmp_pos (tmp_apps_id, position)
select 1 tmp_apps_id, 1 as position union all
select 1 tmp_apps_id, 1 as position union all
select 1 tmp_apps_id, 2 as position union all
select 1 tmp_apps_id, 3 as position union all
select 1 tmp_apps_id, 3 as position union all
select 2 tmp_apps_id, 1 as position
;
/*
Expected result:
tmp_apps_id tmp_pos_position
1 1,2
2 1
*/
如何为每个tmp_pos.position
获得前2个逗号分隔,不同的tmp_apps.id
有可能吗?
答案 0 :(得分:1)
select tmp_apps_id, string_agg(position::text,',')
from (
select tmp_apps_id, position,
row_number() over (partition by tmp_apps_id order by position)
from (
select distinct tmp_apps_id, tmp_pos.position from tmp_pos
) x
) x
where row_number <= 2
group by tmp_apps_id;
答案 1 :(得分:1)
WITH x AS (
SELECT tmp_apps_id
, position
, row_number() OVER (PARTITION BY tmp_apps_id ORDER BY position) AS rn
FROM tmp_pos
GROUP BY 1, 2
ORDER BY 1, 2
)
SELECT tmp_apps_id, string_agg(position::text, ', ')
FROM x
WHERE rn < 3
GROUP BY 1;
这恰好与解决方案@araqnid的发布速度比我快一点 CTE或子查询,在这种情况下,只有两种方法可以做同样的事情。
我的版本在一个重要方面有所不同:
通过使用 GROUP BY
代替 DISTINCT
来获取不同的值,您可以应用window function row_number()
(解决方案的关键元素)相同的查询级别,不需要另一个子查询(或CTE)。
原因是聚合(GROUP BY
)在窗口功能之前应用,而{/ 1}}应用之后。在许多情况下,DISTINCT
和DISTINCT
都提供同样出色的解决方案。在这样的情况下,如果你知道的话,你可以将微妙的差异用于良好的用途。我希望这会快得多。
答案 2 :(得分:0)
使用array_agg
或string_agg
尝试此操作,具体取决于您的Postgres版本:
SELECT tmp_apps_id, array_agg(tmp_pos_position)
FROM tmp_pos_position
GROUP BY tmp_apps_id
在9.0中,使用string_agg
功能:
SELECT tmp_apps_id, string_agg(tmp_pos_position, ',')
FROM tmp_pos_position
GROUP BY tmp_apps_id