PostgreSQL:NOT IN子句导致“列太多”错误

时间:2018-11-15 19:20:04

标签: postgresql in-clause

我正在使用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 :(得分:2)

IN将左侧与右侧匹配,因此右侧的结果集中只需要一列。您可以根据需要执行UNION。

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

或者您可以做两个IN

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

答案 1 :(得分:1)

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)  
 )

答案 2 :(得分:1)

您不在in子句中不能算出数字和列数,应减少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 )  
    )