SQL-如何使用嵌套联接
我正在从服务器收集信息,但我编写的查询没有返回我要查找的所有值。如何使用不同类型的嵌套联接或查询来获取我要查找的所有数据 以下代码段返回我要查找的员工编号的总列表:SQL-如何使用嵌套联接,sql,oracle,join,Sql,Oracle,Join,我正在从服务器收集信息,但我编写的查询没有返回我要查找的所有值。如何使用不同类型的嵌套联接或查询来获取我要查找的所有数据 以下代码段返回我要查找的员工编号的总列表: select papf.employee_number, papf.full_name, paaf.person_id from per_all_people_f papf, per_all_assignments_F paaf where sysdate between papf.effective_start_date an
select papf.employee_number, papf.full_name, paaf.person_id
from per_all_people_f papf, per_all_assignments_F paaf
where sysdate between papf.effective_start_date and papf.effective_end_date
and sysdate between paaf.effective_start_date and paaf.effective_end_date
and paaf.person_id > '0'
and papf.employee_number > '0'
and papf.person_id = paaf.person_id
order by 1;
不幸的是,下一个代码段在返回我想要的所有列时,并没有返回我以前从上述查询中获得的所有行:
select distinct loc.TOWN_OR_CITY city
,COALESCE(CASE WHEN (loc.location_code = 'Foo-Bar') THEN 'Foo-Bar' END, SUBSTR(loc.LOCATION_CODE, 1, INSTR(loc.LOCATION_CODE,'-','1','1')-1), loc.LOCATION_CODE) company
,loc.country
,papf.start_date created
,TRIM(SUBSTR(hou.name, INSTR(hou.name, '-','1','1')+1)) Department
,SUBSTR(pap.name, 1, INSTR(pap.name,'-','1','1')-1) Description
,CONCAT(COALESCE(papf.known_as, papf.first_name), concat(' ', papf.last_name)) DisplayName
,hou.attribute5 Division
,papf.employee_number EmployeeNumber
,papf.first_name givenname
,papf2.full_name Manager
,CONCAT(COALESCE(papf.known_as, papf.first_name), concat(' ', papf.last_name)) name
,pp.phone_number OfficePhone
,papf.known_as OtherName
,loc.region_2 state
,loc.postal_code postalcode
,papf.last_name Surname
,pp.phone_number Telephone#
from per_all_people_f papf
,per_all_positions pap
,per_phones pp
,per_all_people_f papf2
,per_all_assignments_f paaf
,hr_organization_units hou
,hr_locations_all loc
where
papf.person_id = paaf.person_id
and papf2.person_id = paaf.supervisor_id
and paaf.organization_id = hou.organization_id
and loc.location_id = paaf.location_id
and sysdate between papf.effective_start_date and papf.effective_end_date
and sysdate between paaf.effective_start_date and paaf.effective_end_date
and sysdate between papf2.effective_start_date and papf2.effective_end_date
and pp.parent_id = papf.person_id
and phone_type = 'Work Phone'
and paaf.position_id = pap.position_id
;
从我读过的所有帖子中,我的印象是我需要做的工作都在From子句中,但迄今为止我所做的任何尝试都没有成功
如果您能提供关于如何从联接(如我第一次查询中的工作示例)中获取新“表”,然后仅为其余属性引用该表的任何信息,我将不胜感激。第一个查询返回的结果超过5000个,而我的第二个查询只返回2500个。我需要第二个查询中的所有列,而不牺牲第一个查询返回的任何行。我不介意某些列是否有空值。看起来您可以在这里使用语法。这使您可以将子查询用作查询中的表。例如:
with myj as
(
select papf.employee_number, papf.full_name, paaf.person_id
from per_all_people_f papf, per_all_assignments_F paaf
where sysdate between papf.effective_start_date and papf.effective_end_date
and sysdate between paaf.effective_start_date and paaf.effective_end_date
and paaf.person_id > '0'
and papf.employee_number > '0'
and papf.person_id = paaf.person_id
)
select --bunch of stuff
from myj
,anothertable atab
,yetanothertable yatab
where
myj.person_id = atab.col1 ... etc ...
编辑添加:以上只是为了解决OP问题的以下部分
如果您能提供关于如何从联接(如我第一次查询中的工作示例)中获取新“表”,然后仅为其余属性引用该表的任何信息,我将不胜感激
我首先改变了连接语法,而不是所有WHERE条件。 然后,猜测电话类型来自pp表别名
select distinct
loc.TOWN_OR_CITY city,
COALESCE( CASE WHEN (loc.location_code = 'Foo-Bar')
THEN 'Foo-Bar' END,
SUBSTR(loc.LOCATION_CODE, 1, INSTR(loc.LOCATION_CODE,'-','1','1')-1),
loc.LOCATION_CODE ) company,
loc.country,
papf.start_date created,
TRIM(SUBSTR(hou.name, INSTR(hou.name, '-','1','1')+1)) Department,
SUBSTR(pap.name, 1, INSTR(pap.name,'-','1','1')-1) Description,
CONCAT( COALESCE(papf.known_as, papf.first_name), concat(' ', papf.last_name)) DisplayName,
hou.attribute5 Division,
papf.employee_number EmployeeNumber,
papf.first_name givenname,
papf2.full_name Manager,
CONCAT(COALESCE(papf.known_as, papf.first_name), concat(' ', papf.last_name)) name,
pp.phone_number OfficePhone,
papf.known_as OtherName,
loc.region_2 state,
loc.postal_code postalcode,
papf.last_name Surname,
pp.phone_number Telephone#
from
per_all_people_f papf
JOIN per_phones pp
ON papf.person_id = pp.parent_id
and pp.phone_type = 'Work Phone'
JOIN per_all_assignments_f paaf
ON papf.person_id = paaf.person_id
and sysdate between paaf.effective_start_date and paaf.effective_end_date
JOIN per_all_people_f papf2
ON paaf.supervisor_id = papf2.person_id
and sysdate between papf2.effective_start_date and papf2.effective_end_date
JOIN hr_locations_all loc
ON paaf.location_id = loc.location_id
JOIN hr_organization_units hou
ON paaf.organization_id = hou.organization_id
JOIN per_all_positions pap
ON paaf.position_id = pap.position_id
where
sysdate between papf.effective_start_date and papf.effective_end_date
现在,你为什么会丢失记录?我只能提供这样一个事实:您加入的其他表可能有记录,也可能没有记录,这取决于它们的标准。我首先基于主管连接到PAPF2表。那头号人物呢。每个人都有主管吗?如果不是因为你可能有不同部门的不同经理,你可能没有明确的主管。在这种情况下,这些人将被排除在名单之外。若要更正此问题,请将上面的连接更改为LEFT JOIN(左连接),即如果没有基于该连接的管理器,则仍然包括PAAF记录,但要知道PAPF2值将返回null,但至少会返回
同样适用于您的手机标准。您正在明确查找工作电话,但如果有人尚未提供工作电话条目,该怎么办?把它也变成左连接
因此,您可能希望将上面的所有联接都更改为LEFT JOIN,并确保获得所需的所有记录,而不考虑所有相关表是否有记录
然后,一次一个连接将其从左连接更改回连接,并查看有多少记录从结果集中删除。这将告诉您某些记录没有匹配项
既然你知道了,这些人是谁?要解决此问题,请将其更改回左联接,并在WHERE子句中添加一个预期为NULL的条件。例如,第一个关于主管的例子。将查询更改为all LEFT JOIN。然后,对于WHERE子句,添加以下内容
AND papf2.person_id IS NULL
所以,这是说,左联合给我所有的记录,不管匹配。现在,从这一点出发,我只想要那些由于左连接而导致主管的个人ID为NULL的记录,这意味着找不到。因此,现在您可以看到所有没有主管的人,并确认或调整以对这些人应用适当的主管状态
然后,再次尝试手机。。。删除上面的第一个AND子句,然后添加
AND pp.parent_id IS NULL
如果对方有工作电话,我们不在乎。我们只想得到没有电话记录的人的名单
希望这是有意义的…据我所知,您有一些人丢失了电话号码或位置等,也许去一些外部连接会有所帮助?我建议您尝试逐个删除添加到查询中的新表,并查看哪个表连接失败您的第二个查询具有更多筛选器/限制,因此它们得到不同的结果也就不足为奇了。也许你在寻找外部连接?您应该认真考虑使用ANSI连接语法,而不是使用这种非常古老的结构来分离连接和筛选条件——特别是如果您想要外部联接。您需要使用外部连接来获得所需的数据。但首先需要重写以使用ANSI连接内部连接语法,因为使用现有的旧式语法编写外部连接*=容易出错且不明确。我建议您也一个接一个地删除每个附加表,以确定哪一个表需要再次进行外部联接例如,如果第一个查询的ANSI语法是从papf.person\u id=paaf.person\u idYour上的per\u all\u PEOPEN\f papf内部联接per\u all\u分配\u f paaf无法解析记录为m的原因
是的,它只是简化了一个可读性查询的一部分。你是对的,它只是回答了问题的这一部分。我非常感谢你能提供任何信息,说明如何从联接中获得一个新的“表”,比如我第一次查询中的工作示例,然后只引用该表中的其余属性。我应该说得很清楚。不久的将来,当我获得15%的声誉时,我会在这个回答上猛击一支向上的箭。非常感谢您对代码和理论示例的清晰而简单的解释;这是我唯一希望得到的高质量答案。@ThaddeusRix,如果此解决方案有效,单击答案旁边的复选框表示已解决。另外,请查看帮助->浏览,了解其他问题和网站礼仪。欢迎来到S/O。复选标记是你的。再次感谢您给出的令人难以置信的答案,以及您在解释如何实现解决方案方面付出的巨大努力。在papf2和pp上添加左连接完成了这项工作。现在我需要更新大约2500条记录来删除那些空列。