在 SQL 中具有一对多关系的两个表之间建立一对一关系

Make one-to-one relation between two tables that have one-to-many relation in SQL

我有这些疑问:

SELECT        
    dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber, 
    dbo.BaseMaterials.Name AS MaterialName, 
    dbo.MaterialDescriptions.Name AS MaterialDescription, 
    dbo.MaterialDescriptions.Description, 
    dbo.MaterialScopes.ScopeName, dbo.MaterialScopeObjectNames.ObjectName, 
    dbo.MaterialDescriptions.Size1, dbo.MaterialDescriptions.Size2, 
    dbo.MaterialDescriptions.ItemCode, dbo.Materials.Quantity, 
    dbo.Materials.Discipline, dbo.Materials.Id, dbo.Lines.Id AS LineId
FROM
    dbo.Materials 
INNER JOIN
    dbo.Lines ON dbo.Materials.LineId = dbo.Lines.Id 
INNER JOIN
    dbo.BaseMaterials ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id 
INNER JOIN
    dbo.MaterialDescriptions ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id 
INNER JOIN
    dbo.MaterialScopes ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id 
INNER JOIN
    dbo.MaterialScopeObjectNames ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id

它returns 16000 条记录。我有另一个 table 的 joints 名称与 lineId 上的 material table 有关系每个 material 可以有 multi joints所以我添加 joints table 时的查询是这样的:

SELECT        
    dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber, 
    dbo.BaseMaterials.Name AS MaterialName, 
    dbo.MaterialDescriptions.Name AS MaterialDescription, 
    dbo.MaterialDescriptions.Description, dbo.MaterialScopes.ScopeName, 
    dbo.MaterialScopeObjectNames.ObjectName, dbo.MaterialDescriptions.Size1, 
    dbo.MaterialDescriptions.Size2, dbo.MaterialDescriptions.ItemCode, 
    dbo.Materials.Quantity, dbo.Materials.Discipline, dbo.Materials.Id, 
    dbo.Lines.Id AS LineId, dbo.Joints.TestPackageId
FROM
    dbo.Materials 
INNER JOIN
    dbo.Lines ON dbo.Materials.LineId = dbo.Lines.Id 
INNER JOIN
    dbo.BaseMaterials ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id 
INNER JOIN
    dbo.MaterialDescriptions ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id 
INNER JOIN
    dbo.MaterialScopes ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id 
INNER JOIN
    dbo.MaterialScopeObjectNames ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id 
INNER JOIN
    dbo.Joints ON dbo.Materials.LineId = dbo.Joints.LineId

正如您在最后一行中看到的那样,我在 jointsmaterials 之间进行了连接以访问 joints table 中的 testpackageid 列。但我的结果是 returns 220000 条记录。我怎样才能将我的意思是 leftright 的连接类型更改为 returns 16000 记录及其 testpackageId

您不能使用 JOIN。但是,您可以使用 CROSS APPLY:

FROM . . .
     dbo.MaterialScopeObjectNames
     ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id CROSS APPLY
     (SELECT TOP 1 j.*
      FROM dbo.Joints j
      WHERE dbo.Materials.LineId = j.LineId
     ) J

通常,您会在使用 TOP 时包含一个 ORDER BY,这样您就可以控制返回的行。

另请注意,使用 table 别名可使查询更易于编写和阅读。

你可以很容易地通过一个子查询得到它。保持查询不变,并添加一个子查询以从 Joints 获取该信息。

SELECT        dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber, dbo.BaseMaterials.Name AS MaterialName, dbo.MaterialDescriptions.Name AS MaterialDescription, dbo.MaterialDescriptions.Description, 
                         dbo.MaterialScopes.ScopeName, dbo.MaterialScopeObjectNames.ObjectName, dbo.MaterialDescriptions.Size1, dbo.MaterialDescriptions.Size2, dbo.MaterialDescriptions.ItemCode, dbo.Materials.Quantity, 
                         dbo.Materials.Discipline, dbo.Materials.Id, dbo.Lines.Id AS LineId,
                         (select top 1 dbo.Joints.TestPackageId from dbo.Joints where dbo.Joints.LineId = dbo.Materials.LineId)
FROM            dbo.Materials INNER JOIN
                         dbo.Lines ON dbo.Materials.LineId = dbo.Lines.Id INNER JOIN
                         dbo.BaseMaterials ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id INNER JOIN
                         dbo.MaterialDescriptions ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id INNER JOIN
                         dbo.MaterialScopes ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id INNER JOIN
                         dbo.MaterialScopeObjectNames ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id