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
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.
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.
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.
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.
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.
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).
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.
select a.*
from Tablename a
where
(
select count(*)
from Tablename as b
where a.group = b.group and a.id >= b.id
) <= 2
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With