首页 > 解决方案 > 没有连接条件的 T-SQL 匹配记录 1 到 1

问题描述

我有一组实体,它们需要与另一个表中的另一条记录相关联。当我尝试为要匹配的表输出 Id 时,它不起作用,因为您只能从插入、更新等输出。

DECLARE @SignatureGlobalIdsTbl table (ID int,
                                      CompanyBankAccountId int);
INSERT INTO GlobalIds (TypeId)
-- I Cannot output cba.Id into the table since its not from inserted
OUTPUT Inserted.Id,
       cba.Id
INTO @SignatureGlobalIdsTbl (ID,
                             CompanyBankAccountId)
SELECT (@DocumentsGlobalTypeKey)
FROM CompanyBankAccounts cba
     INNER JOIN Companies c ON c.CompanyId = cba.CompanyId
WHERE SignatureDocumentId IS NULL
  AND (SignatureFile IS NOT NULL
   AND SignatureFile != '');


INSERT INTO Documents (DocumentPath,
                       DocumentType,
                       DocumentIsExternal,
                       OwnerGlobalId,
                       OwnerGlobalTypeID,
                       DocumentName,
                       Extension,
                       GlobalId)
SELECT SignatureFile,
       @SignatureDocumentTypeKey,
       1,
       CompanyGlobalId,
       @OwnerGlobalTypeKey,
       [dbo].[fnGetFileNameWithoutExtension](SignatureFile),
       [dbo].[fnGetFileExtension](SignatureFile),
       documentGlobalId
FROM (SELECT c.GlobalId AS CompanyGlobalId,
             cba.*,
             s.ID AS documentGlobalId
      FROM CompanyBankAccounts cba
           INNER JOIN Companies c ON c.CompanyId = cba.CompanyId
           CROSS JOIN @SignatureGlobalIdsTbl s) info
WHERE SignatureDocumentId IS NULL
  AND (SignatureFile IS NOT NULL
   AND SignatureFile != '');

我尝试使用交叉连接来防止笛卡尔生产,但这没有用。我还尝试在某个值上输出行号,但我也无法将其存储在表中。

如果我有两个单独的查询返回相同数量的记录,如何在不创建笛卡尔生产的情况下将记录配对?

标签: sqlsql-servertsqljoin

解决方案


“当我尝试为表格输出 ID 时……它不起作用。”

这似乎是因为您想要输出的列之一实际上并不是插入的一部分。这是一个烦人的问题,我希望 SQL Server 允许我们这样做。

有人可能对此有比我更好的答案,但我通常处理这个问题的方式是

  • 创建我要插入的数据的临时表/等,其中有一列用于 ID(开始为空白)
  • 插入正确数量的行,并将 ID 取出到另一个临时表中,
  • 在原始临时表中适当分配 ID
  • 返回并使用所需的任何其他数据更新插入的行(尽管此处可能不需要,因为您只是插入了一个常量)

这样做是标记/准备好 ID 以供您使用,然后根据需要将它们分配给您的数据,然后用数据填写表格。它相对简单,尽管它确实执行 2 个表命中而不是 1 个。

还可以考虑在事务中完成所有操作以保持数据一致(尽管这里也可能不需要)。

如何将记录配对在一起?

不幸的是,交叉连接会增加行数(左侧的行数乘以右侧的行数)。它在某些情况下很有用,但在这里可能不适用。

我建议当您在上面进行插入时,您会在临时表中获得一个标识符(例如,companyID)并加入该标识符。

如果您没有匹配的记录并且只想按顺序分配它们,您可以使用类似于我在另一个最近的问题中的答案的答案如何使用仅使用一个 ID 的另一个表中的多个值更新临时表中的多行他们之间的共同点?

补充说明

  • 出于性能原因,我建议避免使用表变量(例如,DECLARE @yourtable TABLE)并使用临时表(CREATE TABLE #yourtable)。如果它只是少量的行,那没关系,但随着 SQL Server 假设表变量只有 1 行而变得更大,它会变得更糟
  • 在您的底部语句中,为什么 FROM 子句中有 SELECT 语句?难道你不能摆脱那个 select 语句,让 FROM 子句列出你想要的表吗?

推荐阅读