Postgresql исключая результаты на основе подзапроса - PullRequest
0 голосов
/ 13 марта 2020

У меня есть запрос postgresql, который выглядит следующим образом:

SELECT cats.cat_name,
    cats.breed,
    cats.color,
    cats.gender,
    cats.shelter_location,
    microchip_num.id as microchip,
    release_num.release_num AS release_num,
    cat_files.file,
    max(adoption_num.adoption_num),
        CASE
            WHEN release_num.release_num ~~ 'R%'::text THEN '2'::text
            ELSE '1'::text
        END AS adoptability,
        CASE
            WHEN cats_age.age < '12'::bigint THEN '1'::text
            WHEN cats_age.age > '11'::bigint THEN '2'::text
            ELSE NULL::text
        END AS cat_age
   FROM cats
     JOIN microchip_num ON cats.fk_microchip = microchip_num.id
     JOIN release_num ON release_num.fk_cat_micro = cats.fk_microchip
     LEFT JOIN adoption_num ON adoption_num.fk_microchip_cats = cats.fk_microchip
     LEFT JOIN cats_deceased ON cats.fk_microchip = cats_deceased.cats_micro
     LEFT JOIN cats_returned ON adoption_num.id = cats_returned.adoption_num
     LEFT JOIN cat_files ON cats.fk_microchip = cat_files.fk_cats_key
     LEFT JOIN cats_age ON cats_age.fk_cats_micro = cats.fk_microchip
  WHERE cats.cat_name IS NOT NULL AND microchip_num.microchip !~~ 'null%'::text AND '1'::text =
        case
            WHEN (adoption_num.adoption_num IN ( 
                    select adoption_num.adoption_num 
                        from cats
                            join adoption_num on cats.fk_microchip = adoption_num.fk_microchip_cats 
                except
                    select adoption_num.adoption_num 
                        from cats
                            join adoption_num on cats.fk_microchip = adoption_num.fk_microchip_cats 
                            join cats_returned on adoption_num.id = cats_returned.adoption_num)) 
                THEN '0'::text
            ELSE '1'::text
        END AND cats.shelter_location = '1'::bigint AND cats_deceased.deceased = false
  GROUP BY cats.cat_name, cats.breed, cats.color, cats.gender, cats.shelter_location, microchip_num.microchip, cat_files.file, release_num.release_num, cats_age.age, microchip_num.id, adoption_num.adoption_num;

Проблема, с которой я столкнулся, заключается в следующем разделе:

case
            WHEN (adoption_num.adoption_num IN ( 
                    select adoption_num.adoption_num 
                        from cats
                            join adoption_num on cats.fk_microchip = adoption_num.fk_microchip_cats 
                except
                    select adoption_num.adoption_num 
                        from cats
                            join adoption_num on cats.fk_microchip = adoption_num.fk_microchip_cats 
                            join cats_returned on adoption_num.id = cats_returned.adoption_num)) 
                THEN '0'::text
            ELSE '1'::text
        END

Проще говоря У меня есть таблица FOO , BAR и BAZ . таблица FOO содержит все доступные значения, таблица BAR является дочерним элементом FOO , а BAZ является дочерним столом BAR

графическая демонстрация:

FOO
 |
 |
 -----BAR
 |     |
 |     |
 -----------BAZ

Как я могу сказать postgresql, чтобы извлечь все значения из FOO , где BAR значения NULL , но также включают значения BAZ , только если в FOO отсутствуют дополнительные значения, которые не отображаются в BAZ

пример:

table **FOO**
cars_id   car_type   
   1       Toyota
   2       Ford
   3       Sega
table **BAR**
  id   sold    car_id_foreign_key (id of row from the *Foo* table) date_of_sale
  1     Yes           1                                              1/1/20
  2     yes           2                                              1/2/20
  3     yes           1                                              3/3/20
table **BAZ**  
   Returned    date_returned sale_id_foreign_key (id of row from the *BAR* table*)
      yes           2/2/20         1

В этом примере все, что я хотел бы показать в своем запросе, это автомобиль Sega , поскольку toyota автомобиль был продан и возвращен, но продан снова, и автомобиль Ford был продан и никогда не возвращался

1 Ответ

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

Извините за то, что ленивый, но я только хочу представить ключевую идею здесь ... Включите что-то вроде этого в ГДЕ (выберите FOO):

and not exists (
    select 0 
    from
        BAR
        left join BAZ on BAZ.fk_for_bar = BAR.pk
    where
        BAR.fk_for_foo = FOO.pk
        and BAZ.fk_for_bar is null
)

Используется логика c, что Я могу прямо читать из вашего примера. Что вам нужно, так это то, что автомобиль не должен быть в проданном состоянии. Что означает «проданный статус»? Это означает, что у вас есть счет, который продает его, но никогда не будет другого счета, который бы его помнил. Внутренний запрос выбирает BAR, который не соответствует ни одному из баз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...