Search code examples
mysqlsqlmariadbgreatest-n-per-group

How do you query the nth value from a list of values by group? MySQL


I have a table that looks like this:

| thread_id | time       |
| --------- | ---------- |
| 769       | 1566880174 |
| 769       | 1566880415 |
| 769       | 1566884409 |
| 769       | 1566891158 |
| 769       | 1567215554 |
| 769       | 1567227195 |
| 769       | 1567822758 |
| 773       | 1566973984 |
| 773       | 1567216614 |
| 773       | 1567216833 |
| 773       | 1567216913 |
| 773       | 1567216992 |
| 773       | 1567298692 |
| 774       | 1566977378 |
| 774       | 1567218446 |
| 774       | 1567228282 |
| 774       | 1568241410 |
| 784       | 1567300468 |
| 785       | 1567300549 |
| 785       | 1567310667 |
| 785       | 1567310734 |
| 785       | 1567461936 |

and I need to get the nth value grouped by thread_id. If I'm looking for the 2nd row per thread_id, The output should look like this

| thread_id | time       |
| --------- | ---------- |
| 769       | 1566880415 |
| 773       | 1567216614 |
| 774       | 1567218446 |
| 784       | null       |
| 785       | 1567310667 |

How can I achieve this result?


Solution

  • If you're not on MySQL 8.0, you can do like this (as suggested by @Barmar):

    SELECT thread_id,
           CASE WHEN COUNT(*) >=2 
                THEN SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(TIME ORDER BY TIME) ,',',2),',',-1)
                 ELSE NULL END AS TIME 
      FROM TableA GROUP BY thread_id;