从表中选择行,并将字段替换为另一列中的一个字段(如果存在)

时间:2010-06-09 13:48:38

标签: sql postgresql select join substitution

我正在尝试构建一个执行以下操作的PostgreSQL查询,但到目前为止,我的努力都是徒劳的。

问题: 有两个表:A和B.我想从表A中选择所有列(包含列:id,name,description),并将“A.name”列替换为“B.title”列的值来自表B(具有列:id,table_A_id title,langcode),其中B.table_A_id为5,而B.langcode为“nl”(如果有任何行)。

我的尝试:

SELECT A.name,
 case when exists(select title from B where table_A_id = 5 and langcode= 'nl')
 then B.title
 else A.name
END
FROM A, B
WHERE A.id = 5 and B.table_A_id = 5 and B.langcode = 'nl'

-- second try:
SELECT COALESCE(B.title, A.name) as name
from A, B
where A.id = 5 and B.table_A_id = 5 and exists(select title from B where table_A_id = 5 and langcode= 'nl')

我尝试使用CASE和COALESCE(),但由于我对这两个概念缺乏经验而失败。

提前致谢。

4 个答案:

答案 0 :(得分:3)

araqnid是您正在寻找的答案,我打赌。

但是,如果要强制为每个原始匹配A行返回的行不超过一行,您可能更愿意执行子选择而不是LEFT JOIN。例如:

SELECT A.id, COALESCE(
  ( SELECT max(B.title) FROM B WHERE
    langcode = 'nl' AND B.table_a_id = A.id), A.name ) as name
FROM  A
WHERE A.id = 5

我在这里使用“ max ”来选择任意值,如果有多个值。您可以使用“ min ”或您认为合适的任何内容。

也许这比LEFT JOIN更容易理解,但是(除了两个不完全等效)JOIN将比N个子选择表现更好(更好的是N很大)。

无论如何,从学习的角度来看,理解两者都是好的。

答案 1 :(得分:2)

select A.id, coalesce(B.title, A.name)
from TableA AS A
     left join (select table_a_id, title from TableB where langcode = 'nl') AS B
       on B.table_a_id = A.id
WHERE A.id = 5

答案 2 :(得分:1)

好的,我不确定你的桌子是如何加入的,但这样的事情应该可以完成这项工作:

SELECT            yourcolumnlist,
                  CASE WHEN A.name IS NULL THEN B.title ELSE A.name END
FROM              TableA AS A
INNER JOIN        TableB AS B
ON                A.id = B.table_A_id
WHERE             B.table_A_id = 5
AND               B.langcode = 'nl'

另一种方法是使用COALESCE()函数:

SELECT            yourcolumnlist,
                  COALESCE(A.name, B.title)
FROM              TableA AS A
INNER JOIN        TableB AS B
ON                A.id = B.table_A_id
WHERE             B.table_A_id = 5
AND               B.langcode = 'nl'

答案 3 :(得分:0)

试试这个

select A.id,B.title,A.description from TableA as A inner join tableB as B
on A.id=B.id where B.table_A_id = 5 and B.langcode ='nl'