PostgreSQL: предложение NOT IN вызывает ошибку «слишком много столбцов» - PullRequest
0 голосов
/ 15 ноября 2018

Я использую postgreSQL 10 и пытаюсь создать довольно сложный запрос.

Вот оно

select clothes_id , true as iscon 
 from archive
 where 
 customer_id = 101 and 
 clothes_id <> 1 and 
 shoes_id is null  and 
 clothes_id is not null and 
clothes_id not in 
( select shoes_id, clothes_id from archive where customer_id in
  ( select customer_id from archive where customer_id <> 101 and clothes_id = 1 )  
)

Этот запрос выдает ошибку

> ERROR:  subquery has too many columns LINE 5:                
> clothes_id not in ( select shoes_id, clo...
>                                         ^ SQL state: 42601 Character: 147

Как мне это исправить?

Если вы хотите узнать, что этот запрос пытается сделать, для отладки прочитайте ниже

В архиве находится таблица, которая связывает покупателей, обувь и одежду.

Этот запрос пытается выбрать каждый раз, когда клиент заказывал определенную одежду, а затем проверяет его по другому набору подзапросов. Эти подзапросы проверяют, заказывал ли другой клиент такую ​​же одежду. Если он / она это сделал, то запрос в конечном итоге не вернет эту одежду.

Итак, имея экземпляр архивной таблицы, вот так

clothes - customer - shoes
1          101       2
1          101       6
24         101       null
24         3         2

Запрос не вернет одежду 24, потому что клиент 3 также заказал ее. Так что ничего не вернется.

Спасибо

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

В предложении IN отсутствует еще одно сравнение столбцов - shoes_id

select clothes_id, true as iscon 
 from archive
 where 
 customer_id = 101 and 
 clothes_id <> 1 and 
 shoes_id is null  and 
 clothes_id is not null and 
 (shoes_id, clothes_id) not in 
 (select shoes_id, clothes_id from archive where customer_id in
     (select customer_id from archive where customer_id <> 101 and clothes_id = 1)  
 )
0 голосов
/ 15 ноября 2018

Вы не в предложении не указали номер и столбца. Вы должны уменьшить количество столбцов в select

    select clothes_id , true as iscon 
     from archive
     where 
     customer_id = 101 and 
     clothes_id <> 1 and 
     shoes_id is null  and 
     clothes_id is not null and 
     clothes_id not in 
    ( select  clothes_id from archive where customer_id in
      ( select customer_id from archive where customer_id <> 101 and clothes_id = 1 )  
    )

или вы можете попробовать использовать кортеж для сравнения результата предложения NOT IN

    select clothes_id , true as iscon 
     from archive
     where 
     customer_id = 101 and 
     clothes_id <> 1 and 
     shoes_id is null  and 
     clothes_id is not null and 
    (shoes_id, clothes_id) not in 
    ( select shoes_id, clothes_id from archive where customer_id in
      ( select customer_id from archive where customer_id <> 101 and clothes_id = 1 )  
    )
0 голосов
/ 15 ноября 2018

IN соответствует левой стороне правой стороне, поэтому в результирующем наборе справа должен быть только один столбец.Вы можете сделать СОЮЗ, если хотите.

clothes_id not in 
  ( select shoes_id from archive ...
    union
    select clothes_id from archive ...

Или вы можете сделать два IN s

clothes_id not in 
  ( select shoes_id from archive ...
and clothes_id not in
  ( select clothes_id from archive ...
...