MySQL - 使用具有不匹配行数的多个子查询的结果

时间:2017-06-26 09:51:03

标签: php mysql

我不知道这是否可行,但我正在尝试按照How to specify the parent query field from within a subquery in mySQL?给出的建议在多个子查询中使用MySQL SELECT查询中的值。每个子查询中都有不等数量的结果,我怀疑这是为什么我无法使其工作。

我的数据库比上面的帖子更复杂。我正在处理5个表,如下所示:

  1. substances - 化学物质清单,所有这些物质都有唯一ID(substances.id
  2. ecs - EC编号*值。
  3. cas - CAS编号*值。
  4. ecs_substances - 将substances.id映射到ecs.id。一个substances.id可能会映射到一个或多个 ecs.id
  5. cas_substances - 将substances.id映射到cas.id。一个substances.id可能会映射到一个或多个 cas.id
  6. *这些是用于分类化学品的术语。

    数据如何查找1种物质的示例:

    substances.id  | substances.name
    -------------- | ----------------
    1              | FooBar
    

    分配给多个CAS编号的示例(同样的原则适用于EC,但为了简洁起见仅使用CAS):

    cas_substances.id | substance_id
    --------------------------------
    997               | 1
    ----------------- | ------------
    23423             | 1
    --------------------------------
    

    然后是CAS编号本身:

    cas.id | cas.value
    ------ | ---------
    997    | ABC-123
    ------ | ---------
    23423  | XYZ-876
    ------------------
    

    理想的结果是我想获得每个substances.id, substances.name的列表,其中包含相应的CAS / EC编号列表,理想情况下使用换行符格式化,例如

    substances.id  | substances.name | cas_values         |
    -------------- | --------------- | ------------------ |
    1              | FooBar          | ABC-123 "\n" XYZ-876
    

    我理解逻辑如下:

    1. SELECT * FROM substances
    2. SELECT * FROM cas_substances WHERE cas_substances.substance_id = 1(substances.id
    3. 的结果
    4. SELECT cas.value FROM cas WHERE cas.cas.id = 结果来自2(cas_substances.cas_id
    5. 格式化以处理可能(或可能不是)多个cas_substances行的事实 - 如果存在则在记录之间换行。
    6. 我不明白如何编写从1/2 获得结果的SQL。

      甚至可以在MySQL中执行此操作吗?我正在构建的应用程序是用PHP编写的,但我认为使用SQL只会比在PHP中执行多个子查询要快得多(尽管用PHP编写起来要容易得多)。

2 个答案:

答案 0 :(得分:1)

您可以将这三个表连接在一起,然后使用group bygroup_concat来实现这一目标。

select
    `sub`.*,
    group_concat(cas.`value` separator ' "\n" ') as cas_values
from substances `sub`
left join cas_substances cs on `sub`.id = cs.substance_id
left join cas on cas.id = cs.cas_id
group by `sub`.id

此处demo

注意: GROUP_CONCAT仅适用于mysql。

答案 1 :(得分:0)

接受的答案有效,但我已将其扩展为包括所有5个表:

select
`sub`.*,
group_concat(cas.`value` separator ' "\n" ') as cas_values,
group_concat(ecs.`value` separator ' "\n" ') as ecs_values
from substances `sub`
left join cas_substances cs on `sub`.id = cs.substance_id
left join cas on cas.id = cs.cas_id
left join ecs_substances ec on `sub`.id = ec.substance_id
left join ecs on ecs.id = ec.ec_id
group by `sub`.id