Выберите строки и удалите дубликаты на основе значения столбца - PullRequest
1 голос
/ 13 марта 2019

У меня следующий запрос:

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'

Я бы просто получил строки с идентификаторами 1 и 3.

Какой хороший способ сделать это в PostgreSQL при условии, что к запросу можно применить как смещения, так и ограничения, и я хочу удалить дубликаты.

1 Ответ

1 голос
/ 13 марта 2019

Вместо 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
...