PostgreSQL:比较两组结果不起作用

时间:2018-11-17 18:49:38

标签: postgresql subquery postgresql-10 in-subquery

我有一个表,其中包含3列ID,clothesshoescustomers并将它们相关。

我有一个运行良好的查询:

select clothes, shoes from table where customers = 101(客户101的所有衣服和鞋子)。这将返回

clothes - shoes (SET A)
1          6
1          2
33         12
24         null   

另一个运行良好的查询:

select clothes ,shoes from table where customers in (select customers from table where clothes = 1 and customers <> 101 )(101以外的任何其他顾客的衣服和鞋子,并带有指定的衣服)。返回

shoes - clothes(SET B)
6          null
null         24
1            1
2            1 
12          null
null         26
14           null

现在我想从SET A中获得不在SET B中的所有衣服和鞋子。

所以(例如)select from SET A where NOT IN SET B。这应该只退还衣服33,对吗?

我尝试将其转换为有效的查询:

select clothes, shoes from table where  customers = 101 
and
(clothes,shoes) not in 
 (   
   select clothes,shoes from
   table where customers in 
   (select  customers   from table where clothes = 1 and customers <> 101 ) 
 ) ;

我尝试了不同的语法,但是以上内容看起来更具逻辑性。

问题是我从来没有买衣服33,只是一套空衣服。

该如何解决?怎么了?

谢谢

编辑,这是表的内容

id  shoes   customers   clothes
1    1      1           1
2    1      4           1
3    1      5           1
4    2      2           2
5    2      3           1
6    1      3           1
44   2      101         1
46   6      101         1
49   12     101         33
51   13     102 
52          101         24
59          107         51
60          107         24
62   23     108         51
63   23     108         2
93          124         25
95   6      125 
98          127         25
100  3      128 
103  24     131 
104  25     132 
105         102         28
106  10     102 
107  23     133 
108         4           26
109  6      4   
110         4           24
111  12     4   
112  14     4   
116         102         48
117         102         24
118         102         25
119         102         26
120         102         29
122         134         31

2 个答案:

答案 0 :(得分:1)

PostgreSQL中的except子句的工作方式与minus运算符在Oracle中的工作方式相同。我想这会给你你想要的。

我认为您的查询看起来正确,但我怀疑那些讨厌的null会影响您的结果。就像一个null不等于5(它什么都不是,因此它既不等于也不等于)一样,null也不能不“包含在任何东西中……”

select clothes, shoes
from table1
where customers = 101

except  

select clothes, shoes
from table1
where customers in (
  select customers
  from table1
  where clothes = 1 and customers != 101
)

答案 1 :(得分:1)

对于PostgreSQL,null是未定义的值,因此您必须在结果中消除潜在的null:

select id,clothes,shoes from t1 where  customers = 101 -- or select id... 
and (
 clothes  not in 
 (   
   select COALESCE(clothes,-1) from
   t1 where customers in 
   (select  customers   from t1 where clothes = 1 and customers <> 101 ) 
 ) 
OR 
 shoes not in 
 (   
   select COALESCE(shoes,-1) from
   t1 where customers in 
   (select  customers   from t1 where clothes = 1 and customers <> 101 ) 
  )
 )

如果您想要唯一的对,则可以使用:

select clothes, shoes from t1 where  customers = 101 
and
(clothes,shoes)  not in 
 (   
   select coalesce(clothes,-1),coalesce(shoes,-1) from
   t1 where customers in 
   (select  customers   from t1 where clothes = 1 and customers <> 101 ) 
 ) ;

如果同时选择“衣服和鞋子”列,则无法获得“ 33号衣服” ...

此外,如果您需要确切地知道该客户独特的专栏,衣服或鞋子,您可以使用这个小“技巧”​​:

select id,clothes,-1 AS shoes from t1 where  customers = 101 
and 
 clothes  not in 
 (   
   select COALESCE(clothes,-1) from
   t1 where customers in 
   (select  customers   from t1 where clothes = 1 and customers <> 101) 
 )  
 UNION
  select id,-1,shoes from t1 where  customers = 101 
   and 
   shoes not in 
   (   
    select COALESCE(shoes,-1) from
    t1 where customers in 
    (select  customers   from t1 where clothes = 1 and customers <> 101) 
   )

您的结果将是:

id=49, clothes=33, shoes=-1

(我假设没有ID为-1的衣服或鞋子,您可以在此处输入任何奇异的值)

欢呼