SQL:连接两个表 - 结果表应列出所有 ID(即使是那些不在连接表中的 ID)

Posted

技术标签:

【中文标题】SQL:连接两个表 - 结果表应列出所有 ID(即使是那些不在连接表中的 ID)【英文标题】:SQL: Joining two tables - Result table should list all IDs (even those which are not in the Joining Table) 【发布时间】:2020-08-13 07:07:42 【问题描述】:

我有两张桌子。

第一个表称为“类型”,如下所示:

TypeID  |  Name
1       |  Test1
2       |  Test2
3       |  Test3
4       |  Test4

第二个表叫做“TypeParam”:

TypeID  |  ParamName  |  ParamValue
1       |  heading    |  0.349
1       |  motion     |  1
1       |  shape      |  F
1       |  slumber    |  0|0
3       |  motion     |  2
3       |  shape      |  B
4       |  shape      |  B
5       |  shape      |  F

我想要实现的是(左?)加入两个表。结果应该 列出具有关联形状的所有类型。如果 TypeParam 表中没有形状参数列表,则结果表中的值应为 NULL。如果有 TypeParam 表中未列出的其他 TypeID 条目 类型表,结果表不应包含它们。

结果表应如下所示:

TypeID  |  Name    |  Shape
1       |  Test1   |  F
2       |  Test2   |  null
3       |  Test3   |  B
4       |  Test4   |  B

到目前为止,我尝试的是这个 SQL 语句,它已经列出了所有类型 关联的形状。但是没有列出 TypeParam 表中没有形状条目的类型。我怎样才能做到这一点?我想要结果表中缺少的条目(TypeID = 2,shape = null)。 TypeParam 表中 TypeID = 5 的条目不得列在结果表中,因为它未列在 Type 表中。

SELECT Type.TypeID AS TypeID, Type.Name AS Name, TypeParam.ParamValue AS Shape 
FROM Type LEFT JOIN TypeParam ON TypeParam.TypeID = Type.TypeID
WHERE TypeParam.ParamName = 'shape' 

有什么建议吗?

【问题讨论】:

AND替换WHERE @MKhalidJunaid 我将 WHERE 更改为 AND 并尝试在 MS Access 中对其进行测试,但如果我运行查询,则会弹出一个窗口,提示:不支持 JOIN 表达式。有任何想法吗?使用“WHERE”,查询正在运行。 @user7335295 您用mysql 标记问​​题的事实可能会导致人们认为您使用的是MySQL 而不是MS-Access....我不认为MS- Access 允许在连接谓词中使用常量,因此您需要使用子查询,例如:。 LEFT JOIN (SELECT TypeID, ParamValue FROM TypeParam WHERE ParamName = 'shape') AS tp ON tp.TypeID = Type.TypeID @GarethD 这成功了。非常感谢! 【参考方案1】:

在 MS Access 中,最简单的解决方案可能是关联子查询:

SELECT t.*,
       (SELECT tp.ParamValue
        FROM TypeParam as tp
        WHERE tp.TypeID = t.TypeID AND tp.ParamName = "shape"
       ) as Shape 
FROM Type as t;

注意:如果给定的TypeId 有多个“形状”,这将报告错误。如果这是可能的,我建议您提出一个新的问题,并附上适当的样本数据并解释您想要做什么。

【讨论】:

【参考方案2】:

将您的TypeParam.ParamName = 'shape' 条件移动到ON Cluase

SELECT Type.TypeID AS TypeID, Type.Name AS Name, TypeParam.ParamValue AS Shape 
FROM Type LEFT JOIN TypeParam ON TypeParam.TypeID = Type.TypeID
and TypeParam.ParamName = 'shape' 

【讨论】:

我支持 Fahmi 的回答。在此示例中使用 WHERE 子句时,Left Join 语义丢失。使用 AND 确保 LJ 语义发挥作用。 @Fahmi 我将 WHERE 更改为 AND 并尝试在 MS Access 中对其进行测试,但如果我运行它,则会弹出一个窗口说:不支持 JOIN 表达式。有任何想法吗?使用“WHERE”查询正在运行【参考方案3】:

正如@GarethD 在 cmets 中指出的那样,我使用的是 MS-Access,因此使用子查询解决了这个问题。使用LEFT JOIN (SELECT TypeID, ParamValue FROM TypeParam WHERE ParamName = 'shape') AS tp ON tp.TypeID = Type.TypeID 解决了这个问题。 谢谢!

【讨论】:

以上是关于SQL:连接两个表 - 结果表应列出所有 ID(即使是那些不在连接表中的 ID)的主要内容,如果未能解决你的问题,请参考以下文章

sql聚合函数的使用

mysql怎么将两个表查询出来的结果再去关联下一张表?

SQL的一些查询语句

mysql中inner join和outer join有啥区别?

SQL——左连接(Left join)右连接(Right join)内连接(Inner join)

SQL语句中两个表的连接