【问题标题】:Make one-to-one relation between two tables that have one-to-many relation in SQL在SQL中具有一对多关系的两个表之间建立一对一关系
【发布时间】:2016-09-03 15:23:02
【问题描述】:

我有这些疑问:

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

它返回 16000 条记录。我有另一个名称为joints 的表与lineId 上的material 表有关系,每个material 可以有multi joints,所以当我添加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, 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 表中的testpackageid 列。但我的结果返回 220000 条记录。如何更改连接类型我意思是 leftright 只返回带有 testpackageId16000 记录

【问题讨论】:

    标签: sql-server join right-to-left right-join


    【解决方案1】:

    您不能使用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,因此您可以对返回的行进行一些控制。

    还要注意,表别名的使用使查询更易于编写和阅读。

    【讨论】:

      【解决方案2】:

      您只需一个子查询就可以很容易地得到它。保持您的查询不变,并添加一个子查询以从 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
      

      【讨论】:

      • 谢谢。是的,我知道,但我想也许有更好的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      • 2019-03-31
      • 2018-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多