SQL:从父表中选择数据,并从输出中的两个子表中选择和列

时间:2018-02-15 11:37:22

标签: sql sql-server

我有一个父表,它有两个子数据表以及几个引用表。 (为简单起见,仅显示相关数据)

enter image description here

示例数据:ShiftAnalysis

+----+------------+-----+
| Id | StartTime  | Hrs |
+----+------------+-----+
|  1 | 2018-02-01 |   8 |
|  2 | 2018-02-02 |   8 |
|  3 | 2018-02-03 |   8 |
|  4 | 2018-02-04 |  12 |
+----+------------+-----+

示例数据:ShiftAnalysisItems

+----+-----------+---------+---------------+------------+
| Id | SetupTime | RunTime | ShiftAnalysis | SalesOrder |
+----+-----------+---------+---------------+------------+
|  1 |        60 |     400 |             1 |       7018 |
|  2 |        30 |     450 |             2 |       7019 |
|  3 |        60 |     120 |             3 |       7020 |
|  4 |        60 |     240 |             3 |       7021 |
|  5 |        15 |     195 |             4 |       7022 |
|  6 |        15 |     195 |             4 |       7022 |
+----+-----------+---------+---------------+------------+

示例数据:ShiftAnalysisDownTimeItems

+----+------------------+---------------+------------+
| Id | DownTimeDuration | ShiftAnalysis | SalesOrder |
+----+------------------+---------------+------------+
|  1 |               20 |             1 |       7018 |
|  2 |               30 |             4 |       7022 |
|  3 |               30 |             4 |       7022 |
+----+------------------+---------------+------------+

我想做的是选择:

ShiftAnalysis.StartTime
ShiftAnaylsys.ManHours
Employee.Name
SUM(ShiftAnalysisItems.RunTime)
SUM(ShiftAnalysisItems.SetupTime)
SUM(ShiftAnalysisDownTimeItems.DownTimeDuration)

我创建了这个T-SQL:

Select 
    StartTime, 
    ManHours,
    emp.Name as Employee,
    (Select Sum(RunTime) from ShiftAnalysisItems as sai join ShiftAnalysis as sa1 on sai.ShiftAnalysisItem_ShiftAnalysis = sa1.Id where sa1.Id = sa.Id) as RunTime,
    (Select Sum(SetupTime) from ShiftAnalysisItems as sai join ShiftAnalysis as sa1 on sai.ShiftAnalysisItem_ShiftAnalysis = sa1.Id where sa1.Id = sa.Id) as SetupTime,
    (Select Sum(DownTimeDuration) from ShiftAnalysisDownTimeItems as dti join ShiftAnalysis as sa1 on dti.ShiftAnalysisDownTimeItem_ShiftAnalysis = sa1.Id where sa1.Id = sa.Id) as DownTime
from 
    ShiftAnalysis as sa
join 
    Employees as emp on sa.ShiftAnalysis_Employee = emp.Id
join 
    Machines as m on sa.ShiftAnalysis_Machine = m.Id
join 
    MachineTypes as mt on m.Machine_MachineType = mt.Id
Where
    mt.Description = 'Print'
Order By
    StartTime

这是输出的片段:

+------------+----------+------------+---------+-----------+----------+
| StartTime  | ManHours |  Employee  | RunTime | SetupTime | DownTime |
+------------+----------+------------+---------+-----------+----------+
| 2018-01-02 | 12.00    | Employee 1 | 190.00  | 215.00    |      315 |
| 2018-01-02 | 7.50     | Employee 2 | NULL    | NULL      |      450 |
| 2018-01-02 | 7.50     | Employee 3 | NULL    | NULL      |      450 |
| 2018-01-02 | 9.00     | Employee 4 | 170.00  | 70.00     |      300 |
| 2018-01-02 | 9.00     | Employee 4 | 170.00  | 70.00     |      300 |
| 2018-01-03 | 7.50     | Employee 2 | 165.00  | 100.00    |      185 |
+------------+----------+------------+---------+-----------+----------+

我的问题是,它似乎只是显示停机时间的记录。并非每个ShiftAnalysis记录都有DowTime Children。

此外,看起来我需要对这些内联选择进行分组,因为正如您在上面的员工4中看到的那样,它会显示两次。我已尝试对内联查询进行分组,但我无法理解它,到目前为止似乎没有任何好处。希望有人可以指出我正确的方向?感谢。

1 个答案:

答案 0 :(得分:1)

请检查下面的查询,如果是子查询,请尝试LEFT OUTER JOIN:

SELECT 
    StartTime, 
    ManHours,
    emp.Name AS Employee,
    SUM(ISNUL(RunTime,0)) AS RunTime,
    SUM(ISNUL(SetupTime,0)) AS SetupTime,
    SUM(ISNUL(DownTimeDuration,0)) AS DownTime
FROM 
    ShiftAnalysis AS sa
INNER JOIN
    Employees AS emp ON sa.ShiftAnalysis_Employee = emp.Id
INNER JOIN
    Machines AS m ON sa.ShiftAnalysis_Machine = m.Id
INNER JOIN
    MachineTypes AS mt ON m.Machine_MachineType = mt.Id
LEFT OUTER JOIN 
    ShiftAnalysisItems AS sai ON sa.Id = sai.ShiftAnalysisItem_ShiftAnalysis
LEFT OUTER JOIN 
    ShiftAnalysisDownTimeItems  AS dti ON sa.Id = dti.ShiftAnalysisDownTimeItem_ShiftAnalysis
WHERE
    mt.Description = 'Print'
GROUP BY 
    StartTime, ManHours,  emp.Name 
ORDER BY
    StartTime