简体   繁体   English

MySQL子查询多个结果

[英]MySQL SubQueries Multiple Results

I have a query as follows: 我有一个查询如下:

SELECT event 
FROM log
WHERE user = (SELECT SUBSTRING(details,55) FROM log WHERE details LIKE 'ID: 308%')

I know I can use an inner join or php loop separate here but I have queries where I cannot use inner joins and a problem similar to this happens (which im about to explain). 我知道我可以在此处单独使用内部联接或php循环,但是我有一些查询无法使用内部联接,并且发生了类似的问题(我将要解释)。

The subquery for the where clause returns many email addresses, and I want to then bring up any log events relating to any of them. where子句的子查询返回许多电子邮件地址,然后我想调出与其中任何一个有关的任何日志事件。 My problem is I then get an error message 'Subquery returns more than 1 row'. 我的问题是,然后我收到一条错误消息“子查询返回多于1行”。

If anyone could help that would be much appreciated! 如果有人可以帮助,将不胜感激!

I think this should work: 我认为这应该工作:

SELECT event FROM log
WHERE user IN
  (SELECT SUBSTRING(details,55) FROM log WHERE details LIKE 'ID: 308%')

Use WHERE user IN <subquery> instead of WHERE user = <subquery> . 使用WHERE user IN <subquery>代替WHERE user = <subquery>

However, in my experience, MySQL's performance of IN <subquery> is usually very poor. 但是,以我的经验,MySQL的IN <subquery>性能通常很差。 This can always be rewritten as a JOIN, and that usually performs better. 始终可以将其重写为JOIN,并且通常效果更好。

Here's your example query rewritten as a JOIN: 这是重写为JOIN的示例查询:

SELECT event
FROM log l1
JOIN (SELECT DISTINCT SUBSTRING(details,55) loguser
      FROM log
      WHERE details LIKE 'ID: 308%') l2
ON l1.user = l2.loguser

In this particular case, I suspect performance will be similar. 在这种情况下,我怀疑性能会相似。 Where MySQL usually gets it wrong is when the subquery in the JOIN returns an indexed column, and you're joining with an indexed column in the main table. MySQL通常会出错的地方是JOIN中的子查询返回一个索引列,而您正在与主表中的索引列联接。 MySQL decides to use the index in the subquery instead of the main table, and that's usually wrong (in most cases of queries like this, the subquery returns a small subset of values). MySQL决定在子查询而不是主表中使用索引,这通常是错误的(在大多数此类查询中,子查询返回一小部分值)。

Your other option is to use EXISTS 您的另一个选择是使用EXISTS

SELECT `event`
FROM log
WHERE EXISTS(SELECT *
             FROM log AS log1
             WHERE log1.details LIKE 'ID: 308%'
               AND log.user = SUBSTRING(log1.details,55))

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

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