【问题标题】:MySQL subquery in where clausewhere 子句中的 MySQL 子查询
【发布时间】:2013-03-15 09:59:09
【问题描述】:

我有一个这样的 MySQL 查询:

select 
    *, 
    (select meta_value 
        from nord_usermeta m 
        where meta_key = 'firm' and user_id = s.user_id 
        limit 1) 
        as firm, 
    (select meta_value f
        rom nord_usermeta m 
        where meta_key = 'first_name' and user_id = s.user_id 
        limit 1) 
    as first_name, 
    (select meta_value 
        from nord_usermeta m 
        where meta_key = 'last_name' and user_id = s.user_id 
        limit 1) 
    as last_name     
    from nord_submissions s 
    order by created_at desc

现在我需要使用这样的 where 子句来缩小范围:

select 
    *, 
    (select meta_value 
        from nord_usermeta m 
        where meta_key = 'firm' and user_id = s.user_id 
        limit 1) 
        as firm, 
    (select meta_value 
        from nord_usermeta m 
        where meta_key = 'first_name' and user_id = s.user_id 
        limit 1) 
    as first_name, 
    (select meta_value 
        from nord_usermeta m 
        where meta_key = 'last_name' and user_id = s.user_id 
        limit 1) 
    as last_name 

    from nord_submissions s 
    where firm like '%DG%' 
    order by created_at desc

问题显然在于我使用子查询的方式,但我找不到在 where 子句中引用它的方法。
请帮忙。

【问题讨论】:

  • “问题” .. 什么问题?您能否用错误消息/示例数据库架构/示例数据等扩展您的问题 - 甚至可能是一个小提琴sqlfiddle.com/about.html
  • firm 是用户定义的列..我们也可以称它为虚构列..WHERE 仅适用于数据库列。您应该尝试使用 HAVING 而不是 WHERE

标签: mysql query-optimization


【解决方案1】:

为什么要走这么久...尝试使用 SELF JOIN(在查询中加入相同的表)..见下文 (未测试)

 SELECT ns.*,
        um1.meta_value AS firmName,
        um2.meta_value AS firstName,
        um3.meta_value AS lastName
 FROM nord_submission ns
 INNER JOIN nord_usermeta um1 USING(id) AND meta_key = 'firm'
 INNER JOIN nord_usermeta um2 USING(id) AND meta_key = 'first_name'
 INNER JOIN nord_usermeta um3 USING(id) AND meta_key = 'last_name'
 WHERE um1.meta_value LIKE '%DG%'
 ORDER BY ns.created_at

注意:如果两个表的列名不同,相互引用,则可以将USING(id)替换为ns.user_id=um1.user_id

【讨论】:

    【解决方案2】:

    如果您要使用键而不是列,则必须让应用程序对其进行排序。使用如此多的子查询,您会看到性能下降。

    SELECT *
    FROM nord_submissions 
     INNER JOIN nord_usermeta 
     USING (user_id)
    WHERE (meta_key='last_name' or meta_key='first_name' or (meta_key='firm' and meta_value LIKE '%DG%') )
    ORDER BY created_at desc
    

    【讨论】:

    • 这并不完全错误(当您删除 AND firm like.. 时!),但它的格式不是很好(您的会有多行,而 OP 和 diEcho 的查询每个 nord_submissions 行只有一行。无论如何,我会编辑上面提到的AND firm.. 并为您的努力和替代解决方案 +1。
    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    相关资源
    最近更新 更多