【问题标题】:Whats wrong with this MySQL query - Left Outer Join这个 MySQL 查询有什么问题 - 左外连接
【发布时间】:2017-11-18 10:26:39
【问题描述】:

我的数据库中有三个表,我们称之为: 1. value_type 2. 价值观 3. 组织

每个值都有一个指向 value_type 和 org 的外键引用。此外,每个值类型还有一个默认值。

我正在尝试为所有组织进行左外连接,这样如果值表中存在记录,它将返回该记录中的值,如果记录不存在,它将从value_type 表。但是,当我运行以下查询时,它会为值表中不存在记录的所有组织返回空值。

SELECT 
    o.id as org_id,
    o.name as org_name,
    case when vals.choice is null then vals.default_value else vals.choice END as select_choice,
    vals.choices as choices
FROM orgs o
LEFT OUTER JOIN
    (SELECT 
        v.id as id,
        v.choice as choice,
        v.org_id as org_id,
        v.name as val_name,
        vt.default_value as default_value,
        vt.choices as choices
    FROM value v
    INNER JOIN value_type vt ON v.value_type = vt.id
    WHERE vt.name = 'xyz') vals
ON vals.org_id = o.id

【问题讨论】:

  • 好吧...如果 o.id 的 vals.org_ID 不存在,则所有 vals.records 都将为 null,因此您的 case 语句将始终为此类记录返回 Null 值。换句话说,由于组织的 vals 中没有记录,因此您无法通过这种方式获得默认值。
  • value_type 和 orgs 有什么关系?我们怎么知道为组织选择什么值类型,或者这就是为什么你限制为'xyz'的vt.name?这只会产生 1 条记录?
  • 通常如果你想要一个默认值,它不是基于外键关系,它是一个被认为是默认值的特殊行,而不是与该值在同一行中的另一列。您可以通过具有该行 ID 的单独连接来获得它。你能展示一些示例数据和预期的结果吗?
  • 左连接的定义是如果o.id没有匹配,它的行在由nulls扩展的输出中。

标签: mysql sql join left-join outer-join


【解决方案1】:

看起来很奇怪,但也许您需要将 orgs 交叉连接到 value_Type 然后离开连接到 value?

这种方式来自 org 的记录将列出给定名称的所有值类型;除了默认值,然后如果值中存在记录,我们也专门加入它。然后,coalesce 将选择 vals.choice 之间的第一个非空值(如果存在)和我们知道将存在的交叉连接 vt.default_value。

SELECT 
    o.id as org_id,
    o.name as org_name,
    coalesce(vals.choice, VT.Default_Value)
    VT.choices as choices
FROM orgs o
CROSS JOIN (SELECT id, choices, default_value FROM Value_Type where Name = 'xyz') VT
LEFT OUTER JOIN
    (SELECT 
        v.id as id,
        v.choice as choice,
        v.org_id as org_id,
        v.name as val_name,
        v.value_Type
    FROM value v) vals
  ON vals.org_id = o.id
 AND vals.value_type = vt.id

【讨论】:

  • 是的,我确实需要一个交叉连接,并且为我做到了。
【解决方案2】:

我希望是这样的:

SELECT o.id as org_id,o.name as org_name,
       COALESCE(v.choice, vt.default_value) as select_choice,
       vt.choices as choices
FROM orgs o LEFT JOIN
     value v
     ON v.org_id = o.id LEFT JOIN
     value_types vt
     ON vt.id = v.value_type AND vt.name = 'xyz' ;

但是,当orgsvalue 之间没有匹配记录时,这仍然会返回NULLvalue_typesorgs 之间没有连接。它必须经过value,因此需要orgsvalue 之间的匹配。

【讨论】:

  • 如果组织的值中没有记录,那么由于连接来自 O-->V-->VT,如何从值类型中获取默认值?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多