加入没有关系的多个表

Join Multiple tables with No Relation

我需要加入 3 个 table,这些 table 之间没有任何关系,除了它们都有公共字段(profiledid 和 instanceid) 例如,这3个table是Achievement [0 records],Attachment [6 records]和collegeattended [4 records]

如果我使用内部联接,它将执行笛卡尔积,我将获得 24 条记录,

SELECT a.*, v.*, c.* FROM dbo.Profile p 
LEFT JOIN Achievement v ON p.id = v.ProfileId AND v.InstanceId = 6559
LEFT JOIN Attachment a ON p.id = a.ProfileId AND a.InstanceId = 6559
LEFT JOIN CollegeAttended c ON p.id = c.ProfileId AND c.InstanceId = 6559
WHERE p.Id = 5574443

然而,我需要得到的只是6条记录。

我写了这个查询,得到了 6 条记录。但是,如果驱动 table(在此查询附件中)具有最大行数,则此查询将 运行 正常。

SELECT t1.*, t2.*, t3.* 
FROM (SELECT a.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
    FROM Attachment a
    WHERE a.ProfileId = 5574443 AND a.InstanceId = 6559) AS t1
LEFT OUTER JOIN (
    SELECT b.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
    FROM Achievement b
    WHERE b.ProfileId = 5574443 AND b.InstanceId = 6559) AS t2 ON t1.rn = t2.rn
LEFT OUTER JOIN (
    SELECT c.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
    FROM CollegeAttended c
    WHERE c.ProfileId = 5574443 AND c.InstanceId = 6559) AS t3 ON t1.rn = t3.rn

如果附件有 0 条记录,则此查询不会 return 任何记录。

有什么方法可以编写查询来执行我需要的操作

谢谢

如您所描述的问题,您可以使用full outer join:

SELECT t1.*, t2.*, t3.* 
FROM (SELECT a.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
      FROM Attachment a
      WHERE a.ProfileId = 5574443 AND a.InstanceId = 6559
     ) t1 FULL JOIN
     (SELECT b.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
      FROM Achievement b
      WHERE b.ProfileId = 5574443 AND b.InstanceId = 6559
     ) t2
     USING (rn) FULL JOIN
     (SELECT c.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
      FROM CollegeAttended c
      WHERE c.ProfileId = 5574443 AND c.InstanceId = 6559
     ) t3 
     USING (rn);

虽然 FULL JOINUSING 都是标准的 SQL,但并非所有数据库都支持它们。

如果您的数据库支持该功能,您可以切换到 full joins。如果你的数据库不支持using,这有点棘手,但你可以这样做:

SELECT t1.*, t2.*, t3.* 
FROM (SELECT a.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
    FROM Attachment a
    WHERE a.ProfileId = 5574443 AND a.InstanceId = 6559
) AS t1
FULL JOIN (
    SELECT b.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
    FROM Achievement b
    WHERE b.ProfileId = 5574443 AND b.InstanceId = 6559
) AS t2 ON t1.rn = t2.rn
FULLL JOIN (
    SELECT c.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
    FROM CollegeAttended c
    WHERE c.ProfileId = 5574443 AND c.InstanceId = 6559
) AS t3 ON COALESCE(t1.rn, t2.rn) = t3.rn