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将添加另一个名称列,该名称列应该被实际排除。