J Spring
J Spring

Reputation: 492

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).

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. My problem is I then get an error message 'Subquery returns more than 1 row'.

If anyone could help that would be much appreciated!

Upvotes: 1

Views: 89

Answers (3)

AgRizzo
AgRizzo

Reputation: 5271

Your other option is to use 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))

Upvotes: 0

Barmar
Barmar

Reputation: 780808

Use WHERE user IN <subquery> instead of WHERE user = <subquery>.

However, in my experience, MySQL's performance of IN <subquery> is usually very poor. This can always be rewritten as a JOIN, and that usually performs better.

Here's your example query rewritten as a 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 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).

Upvotes: 2

mavrosxristoforos
mavrosxristoforos

Reputation: 3643

I think this should work:

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

Upvotes: 3

Related Questions