2

我有一个表,其中包含 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
4

2 回答 2

1

对于 PostgreSQL,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 的衣服或鞋子,你可以在这里放任何异国情调的值)

干杯

于 2018-11-18T00:55:12.260 回答
1

PostgreSQL 中的except子句与minusOracle 中操作符的工作方式相同。我认为这会给你你想要的。

我认为理论上您的查询看起来是正确的,但我怀疑那些讨厌的空值正在影响您的结果。就像 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
)
于 2018-11-17T20:29:03.110 回答