【发布时间】:2018-09-27 08:50:36
【问题描述】:
我需要提取每个省注册的学生的统计数据。学生有一个带有邮政编码的地址;邮政编码与行政区相关联;大区与一个省相连。使用内部连接构建选择非常简单。
但是,从学生地址到邮政编码 (code = 1911) 我有一个问题,因为有多个不同郊区名称的邮政编码记录;请参阅下面的数据摘录。
1911 FLORA GARDENS,Vanderbijlpark 7702 VANDERBIJLPARK
1911 HENBYL 7702 VANDERBIJLPARK
1911 LUMIER 7702 VANDERBIJLPARK
1911 NORTHDENE,Vanderbijlpark 7702 VANDERBIJLPARK
1911 PARK SOUTH 7702 VANDERBIJLPARK
1911 STAAL 7702 VANDERBIJLPARK
1911 VANDERBIJLPARK 7702 VANDERBIJLPARK
1911 ZUURFONTEIN 7702 VANDERBIJLPARK
当我像这样进行 INNER JOIN 选择时,
FROM gen.getadr
INNER JOIN stud.iadbio ON getunum = iadstno
INNER JOIN stud.ibvpos ON getpcode = ibvcode
INNER JOIN stud.ibdmag ON ibvcode = ibdcode
不返回任何行。
当我将其更改为左连接时
FROM gen.getadr
INNER JOIN stud.iadbio ON getunum = iadstno
LEFT JOIN stud.ibvpos ON getpcode = ibvcode
LEFT JOIN stud.ibdmag ON ibvcode = ibdcode
我从 ibvpos 和 idbmag 获得了没有数据的行。因此,我无法加入省份表来计算每个省份的学生人数。
有没有一种方法可以表明 getadr(学生地址)和 ibvpos(邮政编码的定义 - 多行)之间的连接必须基于 getpcode 和 ibvcode 之间的唯一匹配?
完整的 select 语句如下所示:
SELECT getunum, getnumtype, getaddrtype, GETCSn, getsdate, getedate, gettac,
getsyscrt
, getadr1, getadr2, getadr3, getadr4, getpcode, ibvtown, ibdname
FROM gen.getadr
INNER JOIN stud.iadbio ON getunum = iadstno
LEFT JOIN stud.ibvpos ON getpcode = ibvcode
LEFT JOIN stud.ibdmag ON ibvcode = ibdcode
where getnumtype = 'I' and getsyscrt = 'S'
AND iadstno = 217244521
AND getaddrtype = 'PA'
AND getedate IS NULL
AND getprimary = 'Y'
ORDER BY getsyscrt, getnumtype, getcsn
任何帮助将不胜感激。
问候,
菲利普
【问题讨论】:
-
将 ibvpos 和 ibdmag 条件从 WHERE 子句移动到 ON 子句以获得真正的左连接结果。 (当在 WHERE 中时,您会得到常规的内部连接结果...)
-
提示:当涉及多个表时,请限定所有列! (即写 tablename.columnname。)
-
嗨@jarlh,感谢您的回复。我不明白您对从 WHERE 子句中移动 ibvpos 和 ibdmag 条件的评论,因为在 WHERE 子句中没有引用这些表。你能澄清一下吗?由于我正在工作的 Db 的结构,我在 SQL 中长大,但没有限定列,但这是很好的做法。
-
您必须决定要使用哪个郊区名称,并改为加入派生表/CTE,例如
join (select ibvcode, max(ibvtown) from stud.ibvpos group by ibvcode) as ibvpos ON getpcode = ibvcode -
谢谢@dnoeth,我创建了一个没有郊区名称的独特子查询;我对名称不是很感兴趣,我只需要将该表加入到省表中。
标签: sql oracle inner-join