【问题标题】:INNER JOIN on multiple rows acts as if rows does not exist多行上的 INNER JOIN 就像行不存在一样
【发布时间】: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


【解决方案1】:

如果没有内部连接结果,则表示 getadr 表中的数据与其他表中的数据不匹配(这些表中没有数据或数据格式不同)。你有这个查询的结果吗? getpcode 不是 null 并且存在于 stud.ibvpos 表中吗?

  SELECT getunum, getpcode 
  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 ibvcode is not null
  AND getnumtype = 'I'
  AND getsyscrt = 'S'
  AND getaddrtype = 'PA'
  AND getedate IS NULL
  AND getprimary = 'Y'

【讨论】:

    【解决方案2】:

    我只是创建了一个子选择,可以像这样唯一地选择邮政编码和管辖区:

    FROM gen.getadr
      INNER JOIN stud.iadbio ON getunum = iadstno
      INNER JOIN 
        (SELECT DISTINCT ibvpcode, ibvcode 
         FROM stud.ibvpos
        ) ON getpcode = ibvpcode
      INNER JOIN stud.ibdmag ON ibvcode = ibdcode
      INNER JOIN stud.innprv ON ibdprovc = innprovc
    

    这给了我预期的结果。

    问候,

    菲利普

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-22
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多