Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL - Give me 3 hits for each type only

I have some kind of impossible request :).

I have a table where one of the columns is named type. I would like to SELECT 3 records for each type in that column. Is that possible?

Note also that I'm using MySQL and Sphinx.

UPDATE: Table structure

id       title        type
1        AAAA         string1
2        CCCC         string2
3        EEEE         string2
4        DDDD         string2
5        FFFF         string2
6        BBBB         string2
6        BBBB         string2

What I want my MySQL to return is (up to 3 records for each type ordered by title):

id       title        type
1        AAAA         string1
6        BBBB         string2
2        CCCC         string2
4        DDDD         string2
like image 521
xpepermint Avatar asked Jan 23 '11 19:01

xpepermint


People also ask

How do I get last 3 entries in SQL?

I want to select the last 3 rows of an sql table. I know I should use SELECT * FROM table ORDER BY DESC LIMIT 3 , but the problem with this code is that it selects the rows from the end. For example, it selects 30, then 29, then 28.

How do I get the first three letters of a name in SQL?

SELECT LEN(column_name) FROM table_name; And you can use SUBSTRING or SUBSTR() function go get first three characters of a column.


2 Answers

select id, title, type
from   (select id, title, type,
               @num := if(@group = type, @num + 1, 1) as row_number,
               @group := type as dummy
        from   your_table
        order by type, title) as x
where  row_number <= 3

(Uses a different article on the same site as Martin Wickman's answer!)

like image 177
Martin Smith Avatar answered Oct 17 '22 09:10

Martin Smith


If you have an index on (type, title), and you know the possible values for type, I believe that dynamic SQL is the way to go (for once) for best performance.

For each possible value of type, add a union all and a select for that specific type. The final query will look like the following query:

(select * from t1 where type = 'string1' order by title limit 3)
  union all
(select * from t1 where type = 'string2' order by title limit 3)
  union all
(select * from t1 where type = 'string3' order by title limit 3);

It executes in less than 1 second on a table with 1,000,000 rows, whereas the others solutions (Martins & Cyberkiwis) takes roughly 11 seconds.

The difference is because the unioned query above can fetch the first three title entries for each type and then stop, whereas the simulated analytics function has to scan the entire table.

like image 34
Ronnis Avatar answered Oct 17 '22 10:10

Ronnis