我有一个包含pk
和dept
列的表格:
pk dept
-------
27 A
29 A
30 B
31 B
33 A
我需要选择第一个连续的组,这是第一个连续的行集,当dept
排序表时,它们都具有相同的pk
值,即预期的结果是:
pk dept
-------
27 A
29 A
在我的例子中,有3个连续的组(AA,BB和A)。组的大小是无限的(可以超过2)。
答案 0 :(得分:2)
以下查询应该执行您想要的操作(我将您的表命名为tx):
SELECT *
FROM tx t1
WHERE NOT EXISTS (
SELECT *
FROM tx t2
WHERE t2.dept <> t1.dept
AND t2.pk < t1.pk);
这个想法是寻找元组,这样就不存在具有较小pk和不同部门的元组。
答案 1 :(得分:0)
记住存储的功能。与使用窗口函数不同,它允许避免读取整个表:
--drop function if exists foo();
--drop table if exists t;
create table t(pk int, dep text);
insert into t values(27,'A'),(29,'A'),(30,'B'),(31,'B'),(33,'A');
create function foo() returns setof t language plpgsql as $$
declare
r t;
p t;
begin
for r in (select * from t order by pk) loop
if p is null then
p := r;
end if;
exit when p.dep is distinct from r.dep;
return next r;
end loop;
return;
end $$;
select * from foo();
答案 2 :(得分:0)
它有点复杂,可能,性能很差,但你可以使用下面的代码实现你想要的。有四个操作:
希望这有帮助。
SELECT fourthOperation.pk,
fourthOperation.dept
FROM (SELECT thirdOperation.pk,
thirdOperation.dept,
DENSE_RANK() OVER (ORDER BY thirdOperation.spreadedIdGroup) denseIdGroup
FROM (SELECT secondOperation.*,
NVL(idGroup, LAG(secondOperation.idGroup IGNORE NULLS) OVER (ORDER BY secondOperation.numRow)) spreadedIdGroup
FROM (SELECT firstOperation.*,
CASE WHEN LAG(firstOperation.rankRow) OVER (ORDER BY firstOperation.numRow) = firstOperation.rankRow
THEN NULL
ELSE firstOperation.numRow
END idGroup
FROM (SELECT yourTable.*,
ROW_NUMBER() OVER (ORDER BY PK) AS numRow,
DENSE_RANK() OVER (ORDER BY DEPT) AS rankRow
FROM ABORRAR yourTable) firstOperation) secondOperation ) thirdOperation) fourthOperation
WHERE fourthOperation.denseIdGroup = 1
答案 3 :(得分:-2)
我不确定我是否理解您的问题,但对于每个pk
的第一个dept
,您可以尝试这样做:
select min(pk) as pk,
dept
from your_table
group by dept