SQL-根据条件将某些列设置为null

时间:2019-02-02 00:23:40

标签: sql postgresql

说我有一个名为people的表,它具有各种属性

  • 名字
  • 姓氏
  • 年龄
  • 电话
  • 电子邮件
  • 地址
  • ...

我想进行查询以返回所有people,但是在特定条件下(一个单独的子查询),我希望将select语句的某些列设置为null以便进行编辑。

所以,说我有基本查询:

SELECT first_name, last_name, age, phone, address
FROM people;

将返回类似于以下内容的表:

|first_name|last_name|age|phone|address       |
------------------------------------------------
|Joe       |Someone  |12 |123  |1234 Somewhere|
|Bob       |Other    |45 |982  |4321 Somewhere|

我希望能够做这样的事情:

SELECT
    first_name,
    last_name,
    if(people.field IN (
        SELECT other_table.some_id FROM other_table WHERE other_table.field = 'is good')
    )
        age, phone, address
    else
        NULL
FROM people;

结果,我希望拥有:

|first_name|last_name|age  |phone|address       |
------------------------------------------------
|Joe       |Someone  |12   |123  |1234 Somewhere|
|Bob       |Other    |NULL |NULL |NULL          |

这有可能吗?

3 个答案:

答案 0 :(得分:2)

应该可以通过以下方法解决此问题:将子查询放在LEFT JOIN中,然后在需要CASE的子句中使用SELECT将输出列设置为NULL

SELECT
    p.first_name,
    p.last_name,
    CASE WHEN s.some_id IS NOT NULL THEN p.age     END AS age,
    CASE WHEN s.some_id IS NOT NULL THEN p.phone   END AS phone,
    CASE WHEN s.some_id IS NOT NULL THEN p.address END AS address
FROM people p
LEFT JOIN other_table s ON s.some_id = p.field AND s.field = 'is good'

您需要注意的是联接的基数。如果other_table中的多个记录与单个people记录匹配,那么您将获得重复的输出行。为避免这种情况,一种解决方案是使用SELECT DISTINCT或通过在查询末尾添加子句GROUP BY p.first_name, p.last_name, p.age, p.phone, p.address来打开聚合。

答案 1 :(得分:2)

我建议使用基于EXISTS的解决方案,该解决方案将能够支持other_table中任何种类的多重性。
注意:您通常希望通过引用子查询中正确的字段来将people中的值与other_table中的值“链接”,这是我对first_name和{{1}所做的操作}。

last_name

PS:如果要将其扩展到其他DBMS,请记住,有些人可能在我输入的地方不支持SELECT first_name, last_name, CASE WHEN MyCondition THEN NULL ELSE age END AS Age, CASE WHEN MyCondition THEN NULL ELSE phone END AS Phone, CASE WHEN MyCondition THEN NULL ELSE address END AS Addess FROM ( SELECT people.*, EXISTS (SELECT 1 FROM other_table WHERE field = 'is good' AND first_name = P.first_name and last_name=P.last_name) as MyCondition FROM people P ) MyTable (此类DBMS的示例:Oracle)。
在这种情况下,您需要执行EXISTS(...)

答案 2 :(得分:1)

您可以通过横向联接来实现:

select p.first_name, p.last_name, s.*
from people p left join lateral
     (select p.age, p.phone, p.address
      from othertable ot
      where ot.other_id = p.field
     ) s;

如果没有匹配项,子查询将不返回任何行-因此所有列均为NULL。否则,它将返回people中的字段。