Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to select the first two records of each group by a "SELECT" command?

For instance I have the following table:

id group data
1 1 aaa
2 1 aaa
3 2 aaa
4 2 aaa
5 2 aaa
6 3 aaa
7 3 aaa
8 3 aaa

What is the best way to select the first two records of each group by a "SELECT" command? If there is no good way to do so, what routine do you suggest?(in PHP)

(model outcome)

1 1 aaa
2 1 aaa
3 2 aaa
4 2 aaa
6 3 aaa
7 3 aaa

I knew that cross-joining by a.id >= b.id in a sub-query can be working but I am looking for a more scalable solution that can be applied on a table with millions of records. Thanks

like image 822
Abby Chau Yu Hoi Avatar asked Apr 09 '13 06:04

Abby Chau Yu Hoi


People also ask

How do you get the first record of each group in SQL?

The first way to find the first row of each group is by using a correlated subquery. In short, a correlated subquery is a type of subquery that is executed row by row. It uses the values from the outer query, that is, the values from the query it's nested into.

How do you select top and rows for each group in SQL Server?

Selecting a top n records for each category from any table, can be done easily using row_number function which generates a sequential integer to each row within a partition of a result set.

Which comes first in a query where or GROUP BY when both occur together?

In the query, GROUP BY clause is placed after the WHERE clause. In the query, GROUP BY clause is placed before ORDER BY clause if used any.

How do you select the first row of a group?

The second approach for selecting the first row of each group is to combine window functions and common table expressions. Window functions are similar to aggregate functions in that both perform calculations across rows. However, the window functions do not group the result into a single row as aggregate functions do.

How to select the first record of each group in access?

MS Access select the first record of each group – using First Function. First of all, Group by Student ID and Name (Home > totals icon), then in the Emergency Contact, select aggregate function First, it means after the data is grouped by Student ID, Name, the first record of each group is returned. Then we get the below result.

How to select multiple columns but only one row from each group?

A problem may surface when you want to select several columns but only one row from each group. Specifically, you may want the first row of each group, that is, the row with a minimum value. Correlated subquery. Window functions + common table expressions. I’ll just skim the theoretical part of window functions and common table expressions (CTEs).

How to aggregate data from multiple MS Access Groups?

MS Access select the first record of each group – using First Function. First of all, Group by Student ID and Name (Home > totals icon), then in the Emergency Contact, select aggregate function First, it means after the data is grouped by Student ID, Name, the first record of each group is returned.


2 Answers

select a.*
from Tablename a
where 
(
   select count(*) 
   from Tablename as b
   where a.group = b.group and a.id >= b.id
) <= 2
  • SQLFiddle Demo
like image 191
John Woo Avatar answered Oct 01 '22 02:10

John Woo


I like this trick, that makes use of GROUP_CONCAT aggregate function, and FIND_IN_SET:

SELECT
  Tablename.*
FROM
  Tablename INNER JOIN (
    SELECT `group`, GROUP_CONCAT(id ORDER BY id) ids
    FROM Tablename
    GROUP BY `group`) grp ON
  Tablename.`group` = grp.`group` AND
  FIND_IN_SET(Tablename.id, ids)<=2
ORDER BY
  Tablename.`group`, Tablename.id

Performances can't be too good, as it can't make use of an index.

Or you can also use this:

SELECT t1.id, t1.`group`, t1.data
from
  Tablename t1 INNER JOIN Tablename t2
  ON t1.`group` = t2.`group` AND t1.id>=t2.id
GROUP BY
  t1.id, t1.`group`, t1.data
HAVING
  COUNT(*)<=2
ORDER BY
  t1.`group`, t1.id, t1.data
like image 23
fthiella Avatar answered Oct 01 '22 02:10

fthiella