说我有一个名为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 |
这有可能吗?
答案 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
中的字段。