简体   繁体   中英

MySQL: limit query or subquery (in left/inner join?)

Apologise in advance, I'm novice in (My)SQL - this should be an easy question for expert DBAs - but I don't even know where to start finding a solution at all. I'm not even sure if I applied LEFT JOIN in the correct way below.

My (DB) structure is quite simple:

I have testsuite s, and several testcase s are linked to each testsuite ("logical entities") During testcase kick-off, I'm creating an entry for each testsuite in the testsuiteinstance table - and one entry in testcaseinstance for each testcase .

My goal is to fetch the last 10 testcaseinstance s of all testcase s belonging to a certain testsuite

This is the query I use to fetch all testcaseinstances :

SELECT * FROM testcaseinstance AS tcinst
LEFT JOIN testsuiteinstance tsinst ON tsinst.id=tcinst.testsuiteinstance_id
LEFT JOIN testsuite ts ON ts.id=tsinst.testsuite_id
WHERE ts.id = 349 ORDER BY tcinst.id DESC;

So, let's say I have two testcase s in a testsuite and both testcase was executed 100 times each. This query gives me 200 rows. If I put "LIMIT 10" at the end, I will only get the last 10 rows for one testcase type, but I want 20 rows (the last 10-10 belonging to the two testcase s)

I'd appreciate some description beside the solution query or a pointer to a "tutorial" I can start looking at related to the topic (whatever would that be :D)

Thanks in advance!

Here's one approach; consider this (slightly contrived) example...

SELECT * FROM ints;

+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+

Let's say we want to return the top 3 even numbers and the top 3 odd numbers from this list. Ignoring for the moment that there's another, simpler, solution to this particular example we can instead do something like this...

SELECT x.*
     , COUNT(*) rank 
  FROM ints x 
  JOIN ints y 
    ON MOD(y.i,2) = MOD(x.i,2) 
   AND y.i >= x.i 
 GROUP 
    BY i 
 ORDER 
    BY MOD(x.i,2) DESC
     , x.i DESC;
+---+------+
| i | rank |
+---+------+
| 9 |    1 |
| 7 |    2 |
| 5 |    3 |
| 3 |    4 |
| 1 |    5 |
| 8 |    1 |
| 6 |    2 |
| 4 |    3 |
| 2 |    4 |
| 0 |    5 |
+---+------+

From here, the process of grabbing just the top 3 from each group becomes trivial...

SELECT x.*
     , COUNT(*) rank 
  FROM ints x 
  JOIN ints y 
    ON MOD(y.i,2) = MOD(x.i,2) 
   AND y.i >= x.i 
 GROUP 
    BY i 
HAVING rank <=3 
 ORDER 
    BY MOD(x.i,2),x.i DESC;
+---+------+
| i | rank |
+---+------+
| 8 |    1 |
| 6 |    2 |
| 4 |    3 |
| 9 |    1 |
| 7 |    2 |
| 5 |    3 |
+---+------+

...and this can be simplified to...

SELECT x.*
  FROM ints x 
  JOIN ints y 
    ON MOD(y.i,2) = MOD(x.i,2) 
   AND y.i >= x.i 
 GROUP 
    BY i 
HAVING COUNT(*) <=3;

+---+
| i |
+---+
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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