我有一个包含2个表的表结构
像这样的桌子人:id name etc.
1 test
2 smith
3 shaw
和第二个表人物,我记录了这样的名字的变化:所以,如果有人因为他结婚或类似的事情改变了他的名字,我仍然有旧的名字。
id personid name etc.
1 1 oldtest
现在我有以下查询
select * from person p
Left join personhist ph on p.id = ph.personid
where (upper(p.name) = upper('oldtest') or upper(ph.name) like upper('oldtest'));
此查询将产生以下结果
id name id personid name
1 test 1 1 oldtest
但我想只有实际的名字结果。所以问题是:有没有办法只显示来自" main"表格如果表格中有记录我加入了吗?
答案 0 :(得分:3)
select p.*, coalesce(p.name, ph.name)
from person p
Left join personhist ph on p.id = ph.personid
where (upper(p.name) = upper('oldtest') or upper(ph.name) like upper('oldtest'))
答案 1 :(得分:2)
但是我想只有一个实体名称的结果。所以问题是有没有办法只显示来自" main"表格如果我加入的表中有记录吗?
只是不要包含您不想要显示的列。您正在使用 SELECT * ,这对任何生产系统来说都不是一件好事。您应该只指定所需的列名。
如果您确实要显示其中一个表的所有列,那么,在您的查询中,因为您已经拥有表名的别名,请使用相同的别名仅包含该表表格栏目。
select p.*
- 这将包含表persons
的所有列,其别名为p
。
select ph.*
- 这将包含表personhist
的所有列,其别名为ph
。
要仅包含选定的列,请明确提及它们。例如 -
select p.id, p.name, ph.personid...
我想你需要的是 -
select p.*, ph.personid
from person p
Left join personhist ph on p.id = ph.personid
where (upper(p.name) = upper('oldtest') or upper(ph.name) like upper('oldtest'));
但我真的怀疑当你只需要显示时,加入的目的是什么只是第一个表。
答案 2 :(得分:0)
正如其他人所提到的那样(我不会打算),您可以通过在SELECT
中指定实际需要的列来获取所需的数据,例如:
select p.name from person p
Left join personhist ph on p.id = ph.personid
where (upper(p.name) = upper('oldtest') or upper(ph.name) like upper('oldtest'));
但我想解决另一个问题。你为什么在这个例子中使用LIKE
?没有任何通配符,因此您可以轻松使用=
。此外,您可以执行以下操作:
SELECT p.name
FROM person p LEFT JOIN personhist ph
ON p.id = ph.personid
WHERE 'OLDTEST' IN ( UPPER(p.name), UPPER(ph.name) );
如果您要搜索以OLDTEST
开头的历史名称,那么您可能希望这样做:
SELECT p.name
FROM person p LEFT JOIN personhist ph
ON p.id = ph.personid
WHERE ( UPPER(p.name) = UPPER('oldtest')
OR UPPER(ph.name) LIKE UPPER('oldtest') || '%');
最后,确保您在PERSON
上有一个基于函数的索引(也可能在PERSONHIST
上有一个):
CREATE INDEX person_name_upper ON person ( UPPER(name) );