【问题标题】:SQL join with criteria on multiple tables使用多个表上的条件进行 SQL 连接
【发布时间】:2015-03-04 18:55:36
【问题描述】:

有人可以帮助了解具有多个 where 条件的外部联接的语法吗?我不确定整体查询的语法,尤其是不确定如何向所有三个表添加条件。

我有三张桌子:

A:员工 (hr_empmstr)

B:好处(hr_beneinfo)

C:工作(hr_emppay)

A:我需要一份所有员工 (A) 的列表。我需要过滤此列表以仅提供在职员工。

B:对于表 A 中的每个员工,我需要根据福利表 (B) 中当前生效的日期行显示当前选定的福利(即使没有我仍然需要一行)。我打算使用诸如benefit_end_dt > GETDATE() 之类的方法来执行此操作。该表每个员工有多行,因此 A:B 是 1:many。

C:我需要根据工作表 (C) 中当前有效日期行显示当前职位。该表每个员工有多行,因此 A:C 是 1:many。

这是我到目前为止的内容,但不确定如何在表 C 中添加以及如何为所有表(活动、最新行等)添加条件

select a.id, a.name, a.type, a.gender, a.hr_status, b.bene_plan, *
from hr_empmstr a
left outer join hr_beneinfo b
    on a.id = b.id
    and b.bene_end > GETDATE()

尝试提交表格的图片,但我没有足够的积分:-(

希望这能提供足够的信息。 谢谢!

【问题讨论】:

  • 你能展示所有三个表的样子吗,即它们有哪些列?这将使某人更容易建议如何正确执行连接。看看这个,我认为您的第一次连接是错误的,因为您使用的是两个表中的唯一标识符,而不是外键和主键。
  • 我正在尝试添加表格和键的屏幕截图,但不知道如何。有什么建议吗?
  • 不确定您使用的是什么操作系统,但您应该能够将屏幕截图保存为图像文件,并在编辑时通过单击“图像”图标将其添加到您的帖子中。跨度>
  • 我在编辑我的原始帖子时发现了它,但它不会让我,因为我在网站上没有足够的积分......
  • 我找到了每个表的 PK 和 FK:beneinfo PK = unique_key, FK = id。 empmstr PK = id,Fk = bargunit。 emppay PK = unique_key,FK = id,pcn。希望这会有所帮助!

标签: sql join syntax max criteria


【解决方案1】:

你在正确的轨道上。

 select a.id, a.name, a.type, a.gender, a.hr_status, b.bene_plan, *
 from hr_empmstr a  
 left outer join hr_beneinfo b
 on a.id = b.id
 left outer join hr_emppay c
 on a.id = c.id
 where b.bene_end > GETDATE() and c.job > GETDATE()

假设你有一个活跃的员工标志,比如 hr_status,在你的 where 语句中添加一个 AND a.hr_status = 'whatever your active flag is' 这应该带来两张桌子上的所有东西。

【讨论】:

  • 我认为这里唯一的问题是您要加入的密钥。我们应该在连接中使用两个表的唯一标识符,而不是各自表的外键/主键。
  • 是的,这正是我所需要的!我之前尝试将条件添加到末尾,但一定是语法错误。我使用了这个语句并从表 A 中添加了一个额外的标准并且它起作用了。
  • 谢谢!并感谢其他所有人的快速反应和天才的头脑!
  • 是否会使用 PK/FK 解决不为每个人显示至少一行的问题?这是我现在使用的查询: select a.id, a.name, a.hr_status,a.bdt, a.gender, d.long_desc, c.actl_hrly * 2080 as Salary, b.bene_plan--, * from hr_empmstr a 左外连接 hr_beneinfo b on a.id = b.id 左外连接 hr_emppay c on a.id = c.id 左外连接 hr_pcntble d on c.pcn = d.pcn 其中 b.bene_end > GETDATE() 和c.pay_end > GETDATE() and d.effend > GETDATE() and a.type like 'FT%' and a.hr_status = 'A'
【解决方案2】:

我们没有你的 bd 结构,所以如果我们假设:

1:对于每条A记录,只有一条bene_end大于GetDate()的记录

2 : 我们在表 c 中有一个字段“IsCurrent”

然后以下查询将起作用:

SELECT  *
FROM hr_empmstr
LEFT JOIN  hr_beneinfo  ON hr_empmstr.id =  hr_beneinfo.id
                        AND hr_beneinfo.bene_end > GETDATE()
LEFT JOIN hr_emppay     ON hr_empmstr.id = hr_emppay.id
                        --AND hr_emppay.IsCurrent = 1
WHERE hr_empmstr.hr_status = 'A'

如果假设不成立,那么您可以使用联接中的子查询将一对多关系缩减为 1:1。 这给了这个:

SELECT  *
FROM hr_empmstr
LEFT JOIN  hr_beneinfo  ON hr_empmstr.id =  hr_beneinfo.id
                        AND hr_beneinfo.unique_key = (SELECT TOP 1 B.unique_key
                                                      FROM hr_beneinfo AS B
                                                      WHERE B.id = hr_empmstr.id
                                                      ORDER BY bene_end DESC)
LEFT JOIN hr_emppay     ON hr_empmstr.id = hr_emppay.id
                        AND hr_emppay.unique_key = (SELECT TOP 1 C.unique_key
                                                    FROM hr_emppay AS C
                                                    WHERE C.id = hr_empmstr.id
                                                    ORDER BY DateFieldToReachLatest DESC)
WHERE hr_empmstr.hr_status = 'A'

另一种解决方案是在 QUERY 上使用 CROSSJOIN,将记录缩减为 1:1。

我不能评论(点不够):

要向我们展示您的数据库结构,您可以在 SQL Management Studio 中右键单击您的表,然后单击“脚本为”->“创建到”。然后将生成的脚本复制粘贴到您的问题中。

【讨论】:

  • 1. B 表在 A 中的每行包含许多行:它是一对多的关系。对于每一位员工,他们可能没有福利行、一个有效福利行或多个有效福利行。以我为例:我注册了医学、牙科、视觉专业,因此我会出现至少三个活动行。
  • 在招聘员工时,您想要所有的福利,还是只想要最后一个? JobTitle 也有同样的问题。
  • 我想要所有有效福利(可能是多行)和单个有效工作(最新生效日期)。
  • 我尝试执行 Script As > Create to 但我们是托管解决方案,显然我没有执行该功能的访问权限。另一个回复回答了我原来的问题,非常感谢您的帮助!
【解决方案3】:

如果我有 3 张桌子

Table a:

id, name, type, gender, hr_status

Table b:

id, a_id, bene_plan, bene_end

Table c:

id, a_id, title

然后我可以加入他们并获取相关信息如下

select
  a.*, b.bene_plan, c.job_title
from
  a
left outer join
  b on b.a_id = a.id and b.bene_end > GETDATE()
left outer join
  c on c.a_id = a.id

请注意,b.bene_end 的条件也可以在 where 子句中。

select
  a.*, b.bene_plan, c.job_title
from
  a
left outer join
  b on b.a_id = a.id
left outer join
  c on c.a_id = a.id
 where
   b.bene_and > GETDATE() and
   a.hr_status = 'A'

更新

如果您在没有匹配的a 记录时仍想查看来自b 的条目,您可以考虑使用full join

【讨论】:

  • 好的,但是如何将选择标准添加到我的表 A 中?我需要将我要拉动的员工类型限制为 hr_status = 'A' 等...我在哪里添加该标准?我试过把它加到最后,但它不起作用。
  • 您可以将它们添加到where 子句中。我已经更新了我的帖子以显示这一点。
  • 是的,根据另一条回复得到了它,但非常感谢这对您有很大帮助!
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多