mmjvox
mmjvox

Reputation: 37

where column in from another select results with limit (mysql/mariadb)

when i run this query returns all rows that their id exist in select from table2

SELECT * FROM table1 WHERE id in (
    SELECT id FROM table2 where name ='aaa'
)

but when i add limit or between to second select :

SELECT * FROM table1 WHERE id in (
    SELECT id FROM table2 where name ='aaa' limit 4
)

returns this error :

This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

Upvotes: 0

Views: 751

Answers (2)

Gordon Linoff
Gordon Linoff

Reputation: 1269753

You are using LIMIT without an ORDER BY. This is generally not recommended because that returns an arbitrary set of rows -- and those can change from one execution to another.

You can convert this to a JOIN -- fortunately. If id is not duplicated in table2:

SELECT t1.*
FROM table1 t1 JOIN
     (SELECT t2.id
      FROM table2 t2
      WHERE t2.name = 'aaa' 
      LIMIT 4
     ) t2
     USING (id);

If id can be duplicated in table2, then:

SELECT t1.*
FROM table1 t1 JOIN
     (SELECT DISTINCT t2.id
      FROM table2 t2
      WHERE t2.name = 'aaa' 
      LIMIT 4
     ) t2
     USING (id);

Another fun way uses LIMIT:

SELECT t1.*
FROM table1 t1
WHERE id <= ANY (SELECT t2.id
                 FROM table2 
                 WHERE t2.name = 'aaa'
                 ORDER BY t2.id
                 LIMIT 1 OFFSET 3
                );

LIMIT is allowed in a scalar subquery.

Upvotes: 1

Barbaros &#214;zhan
Barbaros &#214;zhan

Reputation: 65228

You can use an analytic function such as ROW_NUMBER() in order to return one row from the subquery. I suppose, this way no problem would occur like raising too many rows issue :

SELECT * FROM
(
 SELECT t1.*,
       ROW_NUMBER() OVER (ORDER BY t2.id DESC) AS rn
  FROM table1 t1
  JOIN table2 t2 ON t2.id = t1.id
 WHERE t2.name ='aaa'
) t
WHERE rn = 1

P.S.: Btw, id columns are expected to be primary keys of your tables, aren't they ?

Update ( depending on your need in the comment ) Consider using :

SELECT * FROM
(
 SELECT j.*,
       ROW_NUMBER() OVER (ORDER BY j.id DESC) AS rn2
  FROM job_forum j
  CROSS JOIN 
      ( SELECT t.*,
               ROW_NUMBER() OVER (PARTITION BY t2.id ORDER BY t2.id DESC) AS rn1 
          FROM table2 t2
         WHERE t2.name ='aaa'
           AND t2.id = j.id ) t2 
  WHERE rn1 = 1
) jj
WHERE rn2 <= 10

Upvotes: 0

Related Questions