简体   繁体   中英

MYSQL - how do i select no more than x rows max with the same field value y?

this question is a bit tricky to formulate, so probably has been asked before.

i am selecting rows from a table of interrelating data. i only want a maximum of n rows which have the same value x of some field/column in the table to show up in my set. there is a global limit, in essence i always want the query to return the same amount of rows, with no more than n rows sharing value x. how do i do this?

here's an example of the data (dots are supposed to indicate that this table is large, let's say 20000 rows of data):

some_table
+----+----------+-------------+------------+
| id |  some_id | some_column | another_id |
+----+----------+-------------+------------+
|  1 |       10 |       value |          8 |
|  2 |       10 |       value |          5 |
|  3 |       10 |       value |          2 |
|  4 |       20 |       value |          3 |
|  5 |       30 |       value |          9 |
|  6 |       30 |       value |          1 |
|  7 |       30 |       value |          4 |
|  8 |       30 |       value |          6 |
|  9 |       30 |       value |          7 |
| 10 |       40 |       value |         10 |
| .. |      ... |         ... |        ... |
| .. |      ... |         ... |        ... |
| .. |      ... |         ... |        ... |
| .. |      ... |         ... |        ... |
+----+----------+-------------+------------+

now here's my select:

select * from some_table where some_column="value" order by another_id limit 6

but instead of returning rows with another_id = 1 thru 6 i want to get no more than 2 rows with the same value of some_id. in other words, i'd like to get:

result set
+----+----------+-------------+------------+
| id |  some_id | some_column | another_id |
+----+----------+-------------+------------+
|  6 |       30 |       value |          1 |
|  3 |       10 |       value |          2 |
|  1 |       10 |       value |          3 |
|  7 |       30 |       value |          4 |
|  4 |       20 |       value |          8 |
| 10 |       40 |       value |         10 |
+----+----------+-------------+------------+

note that the results are ordered by another_id, but there are no more than 2 results with the same value of some_id.

how can i best (meaning preferably in one query and reasonably fast) get there? thanks!

select id, some_id, some_column, another_id from (
    select 
    t.*,
    @rn := if(@prev = some_id, @rn + 1, 1) as rownumber,
    @prev := some_id
    from some_table t
    , (select @prev := null, @rn := 0) var_init
    where some_column="value"
    order by some_id, id
) sq where rownumber <= 2
order by another_id;

First we order by some_id, id in the subquery to do the right calculations. Then we order by another_id in the outer query to have correct ordering.

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