简体   繁体   English

如何更改SQL以避免子查询

[英]How to change SQL to avoid subqueries

Here is simplified version of queryie I'm working at: 这是我正在使用的queryie的简化版本:

SELECT 
    r.id,
    r.nr,

    MAX(CASE WHEN (rm.meta_key = 'supplier_id') THEN (SELECT suppliers.title FROM suppliers WHERE suppliers.id = rm.meta_value) ELSE NULL END) AS supplier,
    MAX(CASE WHEN (rm.meta_key = 'client_id') THEN (SELECT clients.name FROM clients WHERE clients.id = rm.meta_value) ELSE NULL END) AS client,

FROM `registries` AS r 
INNER JOIN `registries_meta` AS rm ON `r`.`id` = `rm`.`registries_id`
GROUP BY r.id
LIMIT 100

Is it possible to avoid subquery here? 是否可以在这里避免子查询? I need to tell Mysql "Join registries_metas and if meta_key is client_id JOIN clients.id = meta_value and select clients.name". 我需要告诉Mysql“加入registries_metas,并且meta_key是否为client_id加入JOIN clients.id = meta_value并选择clients.name”。

Thanks. 谢谢。

I believe the logic you want uses just join : 我相信您要使用的逻辑只是join

SELECT r.id, r.nr,
       c.name as client_name, s.title as supplier
FROM registries r INNER JOIN
     registries_meta rm
     ON r.id = rm.registries_id LEFT JOIN
     clients c 
     ON rm.meta_value = c.id AND rm.meta_key = 'client_id' LEFT JOIN
     suppliers s 
     ON rm.meta_value = s.id AND rm.meta_key = 'supplier_id';

If you can have multiple clients/suppliers, you probably want all of them on one row. 如果可以有多个客户/供应商,则可能希望将所有客户/供应商放在同一行。 That suggests aggregation: 这表明聚合:

SELECT r.id, r.nr,
       GROUP_CONCAT(c.name) as client_names,
       GROUP_CONCAT(s.title) as suppliers
FROM registries r INNER JOIN
     registries_meta rm
     ON r.id = rm.registries_id LEFT JOIN
     clients c 
     ON rm.meta_value = c.id AND rm.meta_key = 'client_id' LEFT JOIN
     suppliers s 
     ON rm.meta_value = s.id AND rm.meta_key = 'supplier_id'
GROUP BY r.id, r.nr;

do left join with clients and suppliers table 做与客户和供应商表左联接

SELECT 
    r.id,
    r.nr,
    c.name AS client_name,s.title as supplier
FROM `registries` AS r 
INNER JOIN `registries_meta` AS rm ON `r`.`id` = `rm`.`registries_id`
left join clients c on rm.meta_value=c.id 
left join suppliers s on rm.meta_value=suppliers.id

Try left joining to the clients table. 尝试左联接到clients表。 My intuition tells me that we need to do the pivot in a subquery to find the correct meta value for each key. 我的直觉告诉我,我们需要在子查询中进行数据透视,以找到每个键的正确元值。 Then, we can left join to clients using that meta value (which should be the client ID). 然后,我们可以使用该元值(应该是客户ID)离开加入clients行列。

SELECT
    t.id,
    t.nr,
    t.client AS client_id,
    COALESCE(c.name, '') AS client_name,
    t.supplier AS supplier_id,
    COALESCE(s.title, '') AS supplier_title
FROM
(
    SELECT 
        r.id,
        r.nr,
        MAX(CASE WHEN rm.meta_key = 'client_id' THEN rm.meta_value END) AS client,
        MAX(CASE WHEN rm.meta_key = 'supplier_id' THEN rm.meta_value END) AS supplier
    FROM registries AS r 
    INNER JOIN registries_meta AS rm
        ON r.id = rm.registries_id
    GROUP BY r.id
) t
LEFT JOIN clients AS c
    ON t.client = c.id
LEFT JOIN suppliers AS s
    ON t.supplier = s.id;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM