我有以下查询:
select "houses"."id",
"houses"."uuid",
COUNT(1) OVER() as full_count from "houses"
CROSS JOIN LATERAL jsonb_array_elements(houses.types) house_types
inner join "hoods" on "hoods"."id" = "houses"."hood_id" and "hoods"."owner_id" = 2
inner join "groups" on "groups"."hood_id" = "hoods"."id" and "groups"."manager_id" = 54
where house_types->>'type' = 'big'
group by "houses"."id", "houses"."uuid"
order by lower(houses.name) asc
limit 20
这正确地为我提供了前 20 个类型为“大”的房子,这些房子位于 owner_id 为 2 的引擎盖中,并且哪个引擎盖有关联的组,经理为 54。
现在,问题是有时我会拥有名称相同的房屋,而我想只保留其中一个并移除其余的。例如:
如果我的房子表是这样的:
id, types, name
1, [{ type: 'rating' }], 'white house'
2, [{ type: 'rating' }], 'white house'
3, [{ type: 'rating' }], 'red house'
我只会获取 ID 为 1 和 3 的行。
在 PostgreSQL 中执行此操作的好方法是假设我可以将偏移量和限制都应用于查询,并且我想删除重复项。
最佳答案
代替group by
,使用distinct on
:
select distinct on (lower(h.name)) h.id, h.uuid
COUNT(*) OVER() as full_count
from houses h cross join lateral
jsonb_array_elements(h.types) ht inner join
"hoods" ho
on ho.id = h.hood_id and
ho.owner_id = 2 inner join
"groups" g
on g.hood_id = ho.id and
g.manager_id = 54
where house_types->>'type' = 'big'
order by lower(houses.name) asc
limit 20;
编辑:
select h.*, count(*) over () as full_count
from (select distinct on (lower(h.name)) h.id, h.uuid
from houses h cross join lateral
jsonb_array_elements(h.types) ht inner join
"hoods" ho
on ho.id = h.hood_id and
ho.owner_id = 2 inner join
"groups" g
on g.hood_id = ho.id and
g.manager_id = 54
where house_types->>'type' = 'big'
order by lower(houses.name) asc
) h
limit 20
关于sql - 选择行并根据列的值删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55140195/