1

如何在 PostgreSQL 中模拟 XOR 函数?或者,至少,我认为这是一种异或的情况。

假设数据如下:

id | col1 | col2 | col3
---+------+------+------
1  | 1    |      | 4
2  |      | 5    | 4
3  |      | 8    | 
4  | 12   | 5    | 4
5  |      |      | 4
6  | 1    |      | 
7  |      | 12   | 

我想为那些只填写一列的行返回一列。(暂时忽略col3..

让我们从这个 2 列的例子开始:

SELECT
    id, COALESCE(col1, col2) AS col
FROM
    my_table
WHERE 
    COALESCE(col1, col2) IS NOT NULL -- at least 1 is filled in
AND
    (col1 IS NULL OR col2 IS NULL) -- at least 1 is empty
;

这很好,应该导致:

id | col
---+----
1  | 1  
3  | 8   
6  | 1  
7  | 12

但是现在,我想以col3类似的方式包括在内。像这样:

id | col
---+----
1  | 1  
3  | 8 
5  | 4  
6  | 1  
7  | 12

如何做到这一点是一种更通用的方式?Postgres 是否支持这种方法?

我找不到类似的东西。

4

3 回答 3

5

恰好填充了 1 列的行:

select * from my_table where
   (col1 is not null)::integer 
   +(col1 is not null)::integer 
   +(col1 is not null)::integer 
   =1

1 或 2 行

select * from my_table where
   (col1 is not null)::integer 
   +(col1 is not null)::integer 
   +(col1 is not null)::integer 
   between 1 and 2
于 2015-01-05T23:37:19.307 回答
1

“case”语句可能是你的朋友,“min”聚合函数不会影响结果。

select id, min(coalesce(col1,col2,col3))
from my_table
group by 1
having sum(case when col1 is null then 0 else 1 end+
           case when col2 is null then 0 else 1 end+
           case when col3 is null then 0 else 1 end)=1

[编辑]好吧,我在不使用聚合函数的情况下找到了更好的答案,它仍然基于“案例”的使用,但我认为更简单。

select id, coalesce(col1,col2,col3)
from my_table
where (case when col1 is null then 0 else 1 end+
       case when col2 is null then 0 else 1 end+
       case when col3 is null then 0 else 1 end)=1
于 2013-11-04T15:53:42.370 回答
0

怎么样

select coalesce(col1, col2, col3)
from my_table
where array_length(array_remove(array[col1, col2, col3], null), 1) = 1
于 2015-01-05T20:33:37.547 回答