【问题标题】:Repeat all base table rows for EACH left join row match为每个左连接行匹配重复所有基表行
【发布时间】:2013-01-03 21:07:12
【问题描述】:

我无法简明扼要地描述我需要什么,因此感谢您对编辑标题的任何帮助!

我有 3 张桌子:

  1. Jobs(有JobIDPK)
  2. JobsDetail(有JobID FK 和DepartmentsID FK)
  3. Departments(有DepartmentsIDPK)

Departments 的记录数很少 (~10)

如果我有 10 个部门行,我需要为每个 Jobs 记录重复所有 10 行。不在职位的JobsDetail 记录中的部门ID 将在职位列中显示NULL 值。通过一个 Jobs 记录,典型的 LEFT JOIN 可以按照我想要的方式工作:

Select d.Department, jobs.JobIdentifier
From    Departments d 
LEFT JOIN (Select Distinct j.JobID, j.JobIdentifier, DepartmentID, 
           From   Jobs j
           Join   JobsDetail jd on j.JobID = jd.JobID) jobs on d.DepartmentID = jobs.DepartmentID

产生以下结果:

Department  JobIdentifier
310         NULL
320         NULL
430         NULL
450         NULL
460         NULL
500         NULL
530         1000
533         1000
534         1000
535         NULL

当然,当添加另一个 Jobs 记录时,我会看到:

Department  JobIdentifier
310         2000
320         NULL
430         NULL
450         NULL
460         2000
500         NULL
530         1000
533         1000
534         1000
534         2000
535         NULL

我需要的是这样的:

Department  JobIdentifier
310         NULL
320         NULL
430         NULL
450         NULL
460         NULL
500         NULL
530         1000
533         1000
534         1000
535         NULL
310         2000
320         NULL
430         NULL
450         NULL
460         2000
500         NULL
530         NULL
533         NULL
534         2000
535         NULL

如何做到这一点?

以下是表格中的一些测试数据:

JobID                SubPlantID  JobIdentifier                                      PartFamilyID OrderDate               OrderedBy                                          OrderQuantity DueDate                 SpecialInstructions                                                                                                                                                                                                                                              PrintDate               PrintedBy                                          StartDate               StartedBy                                          ProducedQuantity ReprintNumber CompletedDate           Location
-------------------- ----------- -------------------------------------------------- ------------ ----------------------- -------------------------------------------------- ------------- ----------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------- -------------------------------------------------- ----------------------- -------------------------------------------------- ---------------- ------------- ----------------------- --------------------------------------------------
2                    1           1000                                               1            2012-12-21 13:20:00.000 Keith                                              1             2012-12-28 00:00:00.000                                                                                                                                                                                                                                                                 NULL                    NULL                                               2012-12-28 00:00:00.000 NULL                                               NULL             0             NULL                    NULL
3                    1           2000                                               1            2013-01-03 00:00:00.000 Jon                                                10            2013-01-10 00:00:00.000 NULL                                                                                                                                                                                                                                                             NULL                    NULL                                               NULL                    NULL                                               NULL             0             NULL                    NULL

JobsDetailID         JobID                Operation FirstStartDate          OperationQuantity OperationStatusTypeID OperationDescription                                                                                                                                                                                                                                           DepartmentID WorkCenterID UserName
-------------------- -------------------- --------- ----------------------- ----------------- --------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------ ------------ --------------------------------------------------
1                    2                    10        NULL                    1                 2                     Weld                                                                                                                                                                                                                                                           1            2            keith
2                    2                    20        NULL                    1                 3                     Punch                                                                                                                                                                                                                                                          1            1            keith
3                    2                    30        NULL                    1                 2                     Form                                                                                                                                                                                                                                                           3            5            jon
4                    2                    40        NULL                    1                 3                     Paint                                                                                                                                                                                                                                                          2            4            jon
6                    2                    50        NULL                    1                 3                     Glue                                                                                                                                                                                                                                                           2            4            jwood
9                    2                    60        NULL                    1                 2                     Eat                                                                                                                                                                                                                                                            3            5            jon
10                   3                    20        NULL                    10                1                     Punch                                                                                                                                                                                                                                                          10           18           Jon Wrye
11                   3                    30        NULL                    10                0                     Form                                                                                                                                                                                                                                                           15           29           Jon Wrye
12                   3                    40        NULL                    10                0                     Weld                                                                                                                                                                                                                                                           13           24           Jon Wrye
13                   3                    10        NULL                    10                2                     Start                                                                                                                                                                                                                                                          1            1            jwrye
14                   3                    50        NULL                    10                0                     Finish                                                                                                                                                                                                                                                         1            2            jwrye

DepartmentID Department
------------ --------------------------------------------------
1            534
2            533
3            530
4            535
5            500
6            450
7            430
8            200
9            240
10           232
11           220
12           300
13           460
14           320
15           310

【问题讨论】:

  • 你能创建一个小提琴吗? sqlfiddle.com
  • 你能贴出每张表的数据吗?

标签: sql left-join sql-server-2012


【解决方案1】:

您应该从工作和部门之间的交叉连接开始,然后从那里构建查询:

Select d.Department, jobs.JobIdentifier
From    Departments d cross join
        (select distinct JobIdentifier from Jobs j) ji LEFT JOIN
        (Select Distinct j.JobID, j.JobIdentifier, DepartmentID, 
         From Jobs j Join
              JobsDetail jd
              on j.JobID = jd.JobID
        ) jobs
        on d.DepartmentID = jobs.DepartmentID and
           ji.jobidentifer = jobs.jobIDentifier

我对 JobId 和 JobIdentifier 之间的区别有点不清楚,所以这可能不太正确。

如果您将 ji.JobIdentifier 添加到 select 列表中,您将看到该部门应该属于哪个工作,即使没有匹配项。

【讨论】:

  • 谢谢 - 我会看看这个。 JobID 是 PK(身份),JobIdentifier 基本上是“工作编号”。
  • 完美。 Cross Join 是我缺少的部分。谢谢!
【解决方案2】:

您需要划掉目录(使用交叉连接)、部门和工作,然后对您的关系表进行左连接

http://sqlfiddle.com/#!6/277ec/30

【讨论】:

  • 谢谢@Mr.! Cross Join 就是门票。以前从未见过 SqlFiddle。整洁的东西。
【解决方案3】:

这是怎么做的?

select d.Department, CASE WHEN d.DepartmentId = jj.DepartmentID THEN jj.JobID ELSE NULL END

从部门 d, (SELECT j.JobID, jd.DepartmentID FROM Jobs j left outer join JobDetail jd on j.JobID = jd.JobID) as jj

【讨论】:

    【解决方案4】:

    我不确定我是否完全理解你想要做什么,所以让我们从头开始吧。以下陈述在哪些方面证明不充分?

    Select 
        d.Department,
        j.JobIdentifier
    From
        Departments d
        Left Join JobDetails jd On d.Id = jd.DepartmentId
        Left Join Jobs j On jd.JobId = j.Id
    

    【讨论】:

    • 这不会返回每个 Job/Dept 组合的记录(无论 Job 是否与 Dept 有详细记录)。如果我有 2 个工作并且没有一个有任何详细的 Dept 500,则上述查询仅返回 Dept 500 的一条记录(JobIdentifier 为 NULL)。我需要 500 部门的 2 条记录。希望这是有道理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 2015-01-25
    • 2014-11-05
    • 1970-01-01
    • 2017-08-22
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多