【问题标题】:PostgreSQL Select statement with joins带有连接的 PostgreSQL Select 语句
【发布时间】:2020-08-02 06:17:14
【问题描述】:

我对 SQL 选择相当陌生,我正在尝试从多个表中进行选择,以显示 sync_lwcf_annual_inspection_report_for_active_grants 表中的所有结果,并在匹配值的位置附加其他表中的列。如果没有找到匹配项,只要它显示为 null 并且 sync_lwcf_annual_inspection_report_for_active_grants 没有被省略或重复,就可以了。下面是我尝试过的一些代码。此外,我尝试使用一些左外连接但没有成功。任何帮助将不胜感激。

SELECT
sync_lwcf_annual_inspection_report_for_active_grants.projectnum,
sync_lwcf_annual_inspection_report_for_active_grants.projectnumother,
sync_lwcf_annual_inspection_report_for_active_grants.projecttitle,
sync_lwcf_annual_inspection_report_for_active_grants.projectother,
sync_lwcf_annual_inspection_report_for_active_grants.annual_inspect,
sync_lwcf_annual_inspection_report_for_active_grants.inspect_date,
sync_lwcf_annual_inspection_report_for_active_grants.past_assistance,
sync_lwcf_annual_inspection_report_for_active_grants.public_rec,
sync_lwcf_annual_inspection_report_for_active_grants.park_maintained,
sync_lwcf_annual_inspection_report_for_active_grants.lwfc_sign,
sync_lwcf_annual_inspection_report_for_active_grants.q1a,
sync_lwcf_annual_inspection_report_for_active_grants.q1b,
sync_lwcf_annual_inspection_report_for_active_grants.q2a,
sync_lwcf_annual_inspection_report_for_active_grants.q2b,
sync_lwcf_annual_inspection_report_for_active_grants.q3a,
sync_lwcf_annual_inspection_report_for_active_grants.q3b,
sync_lwcf_annual_inspection_report_for_active_grants.q3c,
sync_lwcf_annual_inspection_report_for_active_grants.q3d,
sync_lwcf_annual_inspection_report_for_active_grants.q3e,
sync_lwcf_annual_inspection_report_for_active_grants.q3f,
sync_lwcf_annual_inspection_report_for_active_grants.q4,
sync_lwcf_annual_inspection_report_for_active_grants.q5,
sync_lwcf_annual_inspection_report_for_active_grants.q6a,
sync_lwcf_annual_inspection_report_for_active_grants.q6b,
sync_lwcf_annual_inspection_report_for_active_grants.q6c,
sync_lwcf_annual_inspection_report_for_active_grants.attest,
sync_lwcf_annual_inspection_report_for_active_grants.attestdate,
sync_lwcf_annual_inspection_report_for_active_grants.localcontact,
sync_lwcf_annual_inspection_report_for_active_grants.regconname,
sync_lwcf_annual_inspection_report_for_active_grants.regcontitle,
tbl_lwcf.status,
tbl_lwcf.grantee,
fc_nc_counties.name_locas,
fc_nc_counties.rrs_regions

FROM
sync_lwcf_annual_inspection_report_for_active_grants,
fc_nc_counties,
tbl_lwcf,
fc_lwcf_grant_boundaries,
fc_lwcf_grant_points,
fc_lwcf_rrs_regions

WHERE
tbl_lwcf.projectnbr37 = fc_lwcf_grant_points.projectid
AND 
fc_lwcf_grant_boundaries.projectid = tbl_lwcf.projectnbr37
AND 
fc_lwcf_grant_boundaries.rrs_regions = fc_lwcf_rrs_regions.rrs_regions
AND
fc_nc_counties.rrs_regions = fc_lwcf_rrs_regions.rrs_regions
AND
sync_lwcf_annual_inspection_report_for_active_grants.projectnum = fc_lwcf_grant_points.projectid

【问题讨论】:

  • 提示:JOINON.
  • 嗯,我要说的第一件事是,尤其是像sync_lwcf_annual_inspection_report_for_active_grants 这样的表名,如果你在表名后写一些字符,它会为该表创建一个别名,然后你可以在其余的查询。如果您说FROM sync_lwcf_annual_inspection_report_for_active_grants r,然后将whatever.sync_lwcf_annual_inspection_report_for_active_grants 的所有其他用法替换为r,该查询会变得更好,例如:SELECT r.projectnum, r.projectnumother ... FROM sync_lwcf_annual_inspection_report_for_active_grants r INNER JOIN...
  • 您的实际问题是什么?你的查询有效吗?如果没有,会发生什么?你得到的行太少了吗?如果有,请说明缺少哪些。还是行太多?可能重复?您使用的连接语法已经过时了近三个世纪。看到你在使用它是令人惊讶的。任何最近(嗯,实际上不到 20 年)的教程或书籍都应该更好地告诉你。
  • @ThorstenKettner 可能不是 3 个 世纪,但我可以坚持几十年! :)
  • @Caius Jard:天哪,错字了。刚看了一部科幻电影;也许这就是原因。 :D 顺便说一句,我喜欢你的回答。非常彻底。

标签: sql postgresql join select


【解决方案1】:

以下是编写 Person 和 Job 之间的连接的方法,请记住,并非每个人都有 Job。它会为所有人以及每个有工作的人生成一个列表,如果他们没有工作,他们的工作信息或工作列中的所有空值:

SELECT * 
FROM
  person p
  LEFT JOIN job j ON p.jobid = j.id

谓词的哪个方向都没有关系(j.id = p.jobid 很好)

左表定义为 LEFT JOIN 之前的表。左连接中的左表是“实心”表 - 将显示与 where 子句匹配的所有行。右表是 RIGHT JOIN 之后提到的表,如果右侧没有与左侧行匹配的行,则其所有列中可能会变得稀疏/有空值

不要写一个 where 子句,然后在右表上指定一个谓词,因为它会导致空值再次消失(左连接然后表现得像内连接),除非你有一个“or righttable.column is null”,这是不必要的罗嗦和如果有多个谓词,还需要仔细括号来解决。

如果您需要指定限制右表中行的内容,请将其作为 ON 子句的一部分。下面是一个查询示例,该查询查找所有 1000 人以及仅属于 manualskilled 类型工作的那 100 个工作信息:

--yes, produces all 1000 people and 900 null job infos, 100 manualskilled job infos
SELECT * 
FROM
  person p
  LEFT JOIN job j ON p.jobid = j.id AND j.jobtype ='manualskilled'


--no, produces just 100 rows, 900 people are missing
SELECT * 
FROM
  person p
  LEFT JOIN job j ON p.jobid = j.id
WHERE
  j.jobtype = 'manualskilled'

发生这种情况是因为与常量字符串“manualskilled”相比,左连接引入的作业类型中的 NULL 已被删除。任何与 NULL 相比的东西都是未知的,这绝不是真的。 where 子句中不正确的内容无法将其放入输出结果集中,正如您现在在查询中发现的那样!

哦,还有最后一点值得一提;混合使用内连接、左连接和右连接时要小心,因为它会对查询输出产生深远影响。如果您首先进行所有内部联接,然后进行左联接,并且如果您需要将任何表连接到您已经左联接的表上,那么您可能会最接近您在逻辑上所期望的结果,然后再次使用左联接。完全避免使用右连接(反过来重写它们,使它们成为左连接)。如果您将一个表内部连接到一个已左连接的表,那么行将再次消失,因为相同的“null 不能与另一个值进行比较并产生一个 true”

【讨论】:

  • Left Join 成功了!感谢您的 cmets 和仔细解释的方法。
  • 没有问题。如果答案是您最终使用的答案,请单击灰色勾号将其变为绿色 - 这意味着其他人可以从仪表板看到它已接受的答案。支持对您也有用的答案。可以对任意数量的答案进行投票,但只能勾选一个。勾选的答案也可以投票
猜你喜欢
  • 2017-03-31
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
相关资源
最近更新 更多