将 SQL 表重新连接在一起以创建报告

问题描述 投票:0回答:2

我们有一个系统可以跟踪 MS SQL 数据库中的包。每包包含 1-3 盒。所有包裹都至少有一个盒子,“BoxSide”。此外,它们旁边还可能有一个“BoxOuter”,并且该盒子内部可能有“BoxInner”。每个盒子里都有我们保存数据的内容。

因此,总共有五个单独的表:一张包含包装信息,一张代表每个盒子(侧面、外部和内部),还有一张包含每个盒子内容的数据。它们之间的关系如下图所示:

表格图

我想要做的是运行一个查询,将所有数据放在一个报告中,每个包有一条记录,每个框的内容有一个字段,将不适用的字段留空。比如:

Package.*、BoxSide.Data1、Boxside.Data2、BoxOuter.Data1、BoxOuter.Data2、BoxInner.Data1、BoxInner.Data2

重申:

  • 我想要每个包裹都有一条记录
  • 每个包裹都有一个 BoxSide
  • 一个包裹可能有一个 BoxOuter
  • BoxOuter 可能有 BoxInner

我尝试了各种连接来将这些数据链接回一起,但我似乎总是以丢失包裹(如果它们没有特定的盒子类型)或不同盒子类型的同一包裹多次重复记录而告终。这里列出了太多失败的尝试。

有懂 SQL 的人可以帮我做一个可以做到这一点的查询吗?

sql sql-server t-sql report
2个回答
0
投票

您需要使用

LEFT JOIN
来获取
Package
中的每条记录,无论它在其他表中是否有对应的值:

    SELECT P.ID, p.Time, P.Type, P.Name, P.location,
    s.ID, sc.ID, sc.Data1, sc.Data2,sc.Data3
    o.ID, oc.ID, oc.Data1, oc.Data2, oc.Data3
    i.ID, ic.ID, ic.Data1, ic.Data2, ic.Data3
    FROM Package p
    LEFT JOIN BoxSide s ON p.ID = s.PackageID
    LEFT JOIN Contents sc ON s.ID = sc.ParentID
    LEFT JOIN BoxOuter o ON p.ID = o.PackageID
    LEFT JOIN Contents oc ON o.ID = oc.ParentID
    LEFT JOIN BoxInner i ON o.ID = i.BoxOuterID
    LEFT JOIN Contents ic ON i.ID = ic.ParentID

请注意,您还必须多次

LEFT JOIN
Contents
表,每次使用不同的别名将其链接到每个父表。


0
投票

您是否尝试过在 BoxOuter 和 BoxInner 上应用左连接?无论右侧是否有匹配项,这都应该返回您的软件包。

SELECT Package.*,
       bsc.Data1,
       bsc.Data2,
       boc.Data1,
       boc.Data2,
       bic.Data1,
       bic.Data2
FROM Package p
INNER JOIN BoxSide bs ON p.id = bs.packageid
LEFT JOIN BoxOuter bo ON p.id = bo.packageid
LEFT JOIN BoxInner bi ON bo.id = bi.boxouterid
INNER JOIN Contents bsc ON bs.id = bsc.parentid
INNER JOIN Contents boc ON bo.id = boc.parentid
INNER JOIN Contents bic ON bi.id = bic.parentid
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.