【问题标题】:MySQL Query That Can Pull the Data I am Seeking?可以提取我正在寻找的数据的 MySQL 查询?
【发布时间】:2011-03-04 12:47:07
【问题描述】:

在我正在进行的项目中,我被 Hades 的表格结构所困扰。要记住两件事:

  1. 我现在无法更改表结构。我暂时坚持下去。
  2. 查询是动态生成的,不是硬编码的。因此,虽然我要求一个可以提取这些数据的查询,但我真正致力于的是一种能够生成我需要的查询的算法。

希望我能解释这个问题,而不会让你的眼睛发呆,让你的大脑崩溃。

我们有一个实例表,看起来(简化)如下:

实例 InstanceID 活动 1年 2年 3岁 4 牛 5年 6 是

那么,沿着这些方向有多个数据表:

表格1 InstanceID field1 reference_field2 约翰一书 5 2 莎莉 NULL 3 弗雷德 6 4 乔 NULL 表2 InstanceID 字段3 5 1 6 1 表3 InstanceID fieldID field4 5 1 霍华德 5 2 詹姆斯 6 2 贝蒂

请注意,Table1 中的 reference_field2 包含对另一个实例的引用。 Table2 中的 Field3 稍微复杂一些。它包含表 3 的 fieldID。

我需要的是一个查询,它会给我一个如下列表:

InstanceID 字段 1 字段 4 1 约翰霍华德 2 莎莉 3 弗雷德

问题是,在我目前的查询中,我没有得到 Fred,因为在 Table3 中没有字段 ID 1 和 InstanceID 6 的条目。所以,到目前为止我能得到的最好的列表是

InstanceID 字段 1 字段 4 1 约翰霍华德 2 莎莉

本质上,如果表1中有字段2的条目,而表3中没有字段2包含instanceID和字段3包含字段ID的条目,我没有从字段1中获取数据.

我已经查看了连接,直到我脸色发青,当 table3 没有条目时,我看不到处理这种情况的方法。

【问题讨论】:

  • MySQL 是否允许外部连接?

标签: sql mysql join left-join


【解决方案1】:

左连接...

SELECT a.InstanceID, b.field1, d.field4
FROM instances AS a 
    JOIN Table1 AS b ON a.InstanceID = b.InstanceID
    LEFT JOIN Table2 AS c ON b.reference_field2 = c.InstanceID
    LEFT JOIN Table3 AS d ON (c.InstanceID = d.InstanceID AND c.field3 = d.fieldId)
WHERE a.active = 'Y'

两个左连接应该处理没有其他行的情况...

【讨论】:

  • 您的查询有一个问题。我需要要求表 3 中的 fieldID 与表 2 中为实例列出的 FieldID 相同。而且,正是 WHERE 子句在我的结果中似乎扼杀了 Fred。
  • 首先,连接确实要求表 3 中的 fieldID 与表 2 中的相同(这是 table3 连接的 ON 子句的第二部分)。如果 WHERE 子句正在杀死 Fred(根据您的示例数据,它不应该是),那么可能 active for fred 真的是“Y”(带空格)?或者不仅仅是简单的'Y'......?
  • 我想我开始看到基于您发布的解决方案的路径。我需要删除 Where 子句并改用连接语法。实际的查询比这个例子更糟糕,但我想我确实看到了一点关于现在如何做的暗示谢谢。艾米
  • 好吧,我很乐意提供帮助。一句话警告。不要将 where 子句条件放在 join 子句中(反之亦然)。它可能会阻止 MySQL 的优化器找出正确的执行计划(以及显着降低可读性,尽管这可能是一个问题 ;-)。
【解决方案2】:

如果您发布您的查询会有所帮助,因为我认为您在此处的表格描述中有一些错误,因此不太清楚表格是如何连接的。

无论如何,您的查询中可能有一个内部联接(通常写为JOIN)。将其替换为左外连接 (LEFT JOIN)。它不需要正确的表来包含行并返回NULL 而不是实际值。

【讨论】:

  • 最接近实际查询的是 SELECT Instances.InstanceID,Table1.field1,Table3.field4 FROM Instances LEFT JOIN Table1 ON Instances.InstanceID = Table1.InstanceID LEFT JOIN Table2 ON Instances.InstanceID = Table1.fieldID2 LEFT JOIN Table3 ON Table2.InstanceID = Table3.InstanceID WHERE Instances.active = 'Y' AND (Table3.fieldID = Table2.fieldID OR Table1.field2 IS NULL) ORDER BY Table1.field1 asc 实际查询更多神秘,因为表名都是动态生成的。
  • 好吧,如果没有看到确切的表格,就很难提供帮助。例如,在这里您加入“Instances.InstanceID = Table1.fieldID2”上的表。这对我来说毫无意义,并且与您在问题中写的不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 2012-01-05
  • 2011-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多