如何使用 3 个表在 SQL 查询中获得完整结果,其中 1 个表保持 2 个表的关系?
Posted
技术标签:
【中文标题】如何使用 3 个表在 SQL 查询中获得完整结果,其中 1 个表保持 2 个表的关系?【英文标题】:How can I get full results in SQL query using 3 tables, where 1 of them keeps relation of 2 another? 【发布时间】:2020-09-30 14:12:57 【问题描述】:我需要帮助编写查询以显示我想要的结果。
“表 3 - 关系”保留表 1 和表 2 之间的所有关系。通常,表 3 中不存在表 1 和 2 之间的关系,所以我想在结果中看到缺失的关系所有表 1 行 - 请参阅下面的预期结果。 我无法修改这些表 - 我只有 SELECT 权限。
数据和预期结果如下:
Table 1 - a:
a_id, a_name
e.g.:
1 A
2 B
Table 2 - b:
b_id, b_name
e.g.:
1 X
2 Y
Table 3 - relation:
asset1_id (it's always id from Table 1), asset2_id (it's always id from Table 2), relation_type
e.g.:
1 1 covers
1 2 covers
预期结果:
Table1_name, Table2_name, Table3_relation_type (including NULL for b_name and relation_type when such relation does not exist in Table 3 - relation)
e.g.
A X covers
A Y covers
B NULL NULL
我无法获得带有 NULL 的第三个预期行。
【问题讨论】:
表之间大概有关系吧。你应该解释它们是什么。 您必须在所有表中创建唯一的 Id,然后使用唯一的 Id 合并表。通过在表中创建主键和外键来使用SQL连接,并在连接这些表后获取数据。 我澄清了表之间的关系。我不能修改表,我只有 SELECT 权限。 检查这个,它可能对你有帮助。 ***.com/questions/2008853/… 上面的文章给了我没有我期望得到的第 3 行的结果 - 所以当表 1 的某些行在 Tbale 3 中没有关系时,我仍然看不到结果中的 NULL。 【参考方案1】:我认为这个查询会产生这些结果。
select a.name as a_name,b.name as b_name, r.relation_type from relation r
join a on a.id=r.asset1_id
join b on b.id=r.asset2_id
union
select a.name as a_name,b.name as b_name,r.relation_type from relation r
full outer join a on a.id=r.asset1_id
full outer join b on b.id=r.asset2_id
where a.id is null or b.id is null
【讨论】:
当表 1 中的项目与表 2 中的任何表 3 行都不匹配时,这种方式没有预期的 NULL。【参考方案2】:有了你的数据样本,你可以试试这个。
它应该适用于 hive 或 impala。
SELECT t1.name ,t2.name ,r.relation_type
FROM relation r
FULL OUTER JOIN table1 t1 ON(t1.id = r.id1)
FULL OUTER JOIN table2 t2 ON(t2.id = r.id2);
+------+------+---------------+
| name | name | relation_type |
+------+------+---------------+
| A | X | covers |
| A | Y | covers |
| B | NULL | NULL |
+------+------+---------------+
【讨论】:
这也没有让我得到预期的 NULL。我认为这是因为有很多关系类型,而我只对 r.type='Control' 感兴趣,并且在应用此过滤器时,我丢失了所有没有关系的表 1 行。【参考方案3】:WITH
cte_A AS (
SELECT id as a_id, name as a_name
FROM a
),
cte_C AS (
SELECT c.asset_id1 as a_id, b.name, c.relation
FROM c
LEFT JOIN b ON c.id=b.asset_id2
)
SELECT cte_A.a_name, cte_C.name as c_name, cte_C.relation
FROM cte_A
LEFT JOIN cte_C ON cte_A.a_id=cte_C.a_id
【讨论】:
这完全符合预期,可能可以简化以避免第一次 cte。以上是关于如何使用 3 个表在 SQL 查询中获得完整结果,其中 1 个表保持 2 个表的关系?的主要内容,如果未能解决你的问题,请参考以下文章