加入没有关系的多个表
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 JOIN
和 USING
都是标准的 SQL,但并非所有数据库都支持它们。
如果您的数据库支持该功能,您可以切换到 full join
s。如果你的数据库不支持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
我需要加入 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 JOIN
和 USING
都是标准的 SQL,但并非所有数据库都支持它们。
如果您的数据库支持该功能,您可以切换到 full join
s。如果你的数据库不支持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