Sql 具有左联接但不显示联接表内数据的选择
我有一个有两张桌子的桌子结构 像这样的餐桌上的人:Sql 具有左联接但不显示联接表内数据的选择,sql,oracle,select,join,left-join,Sql,Oracle,Select,Join,Left Join,我有一个有两张桌子的桌子结构 像这样的餐桌上的人: id name etc. 1 test 2 smith 3 shaw 第二个表格是personhist,我记录了名字的变化,比如:如果有人因为结婚或者类似的事情而改变了他的名字,我仍然会用老名字 id personid name etc. 1 1 oldtest 现在我有以下问题 select * from person p Left join personhist ph on p.id = ph
id name etc.
1 test
2 smith
3 shaw
第二个表格是personhist,我记录了名字的变化,比如:如果有人因为结婚或者类似的事情而改变了他的名字,我仍然会用老名字
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”表中的数据
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'))
但我只想要actuel名称结果。所以问题是,如果我连接的表中有记录,是否有一种方法可以只显示“main”表中的数据
只是不要包含您不想显示的列。您使用的是选择*,这在任何生产系统上都不是一件好事。您应该只指定那些必需的列名
如果确实要显示其中一个表的所有列,则在查询中,由于表名已有别名,请使用相同的别名仅包括该表的列
选择p.*
-这将包括别名为p
的表persons
的所有列
select ph.
-这将包括表personhist
中别名为ph
的所有列
要仅包括选定列,请明确提及它们。比如说-
选择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'));
但我真的很怀疑当您只需要显示第一个表时,加入的目的是什么
但我只想要actuel名称结果。所以问题是,如果我连接的表中有记录,是否有一种方法可以只显示“main”表中的数据
只是不要包含您不想显示的列。您使用的是选择*,这在任何生产系统上都不是一件好事。您应该只指定那些必需的列名
如果确实要显示其中一个表的所有列,则在查询中,由于表名已有别名,请使用相同的别名仅包括该表的列
选择p.*
-这将包括别名为p
的表persons
的所有列
select ph.
-这将包括表personhist
中别名为ph
的所有列
要仅包括选定列,请明确提及它们。比如说-
选择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'));
但我真的很怀疑,当您只需要显示第一个表时,加入的目的是什么。正如其他人所提到的(我不再赘述),您可以通过在选择中指定实际需要的列来获得所需的数据,例如:
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) );
正如其他人所提到的(我不再赘述),您可以通过在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) );
我的第一个想法是“不要使用select*
”,但我不太确定您想看到什么-只是p.name
值?那为什么要加入呢?也许你可以展示你的预期结果,以及一些更丰富的数据?@AlexPoole我想看看person的所有内容,但如果我用旧名称搜索,我想看看新名称。我的第一个想法是“不要使用select*
”,但我不太确定你想看到什么-只有p.Name
值?那为什么要加入呢?也许你可以展示你的预期结果,以及更多不同的数据?@AlexPoole我想看到person的一切,但如果我用旧名字搜索,我想看到新名字为什么合并?这个名字无论如何都会被复制。要求只显示一个名称列,该列在查询中由p.*
给出,现在合并将添加另一个实际应排除的名称列。为什么合并?这个名字无论如何都会被复制。要求只显示一个名称列,在查询中由p.*
给出,现在coalesce将添加另一个名称列,该名称列应该被实际排除。