简体   繁体   中英

How do I get distinct rows by a column?

I have a huge number of rows that I'd like to get say, last 5 records inserted in that database from 10 different users. If the same user inserted the last 3 rows into database, we must get one row, skip the others two and move to get a row per user, until it count up to 5.

A database like that:

user_id | news_id | title
1       | 1       | foo-1
2       | 2       | foo-2
3       | 3       | foo-3
1       | 4       | baa
4       | 5       | baa0
5       | 6       | baa1
5       | 7       | baa2
6       | 8       | baa3
7       | 9       | baa4

Should return:

user_id | news_id | title
1       | 1       | foo-1
2       | 2       | foo-2
3       | 3       | foo-3
4       | 5       | baa0
5       | 6       | baa1

The current filter was done by PHP, like this:

$used = array();
while ($data = mysql_fetch_array($query)) {
   $uid = $data['user_id'];
    if(in_array($uid, $used))
        continue;
    array_push($used, $uid);

// do something with data
}

But I want to refactor it, and do the filter purely by mysql, if possible. I don't know much MySql and that's why I'm having problem to archive this...

Here's what I've tried

select DISTINCT(user_id), news_id, title from XXX
WHERE GROUP BY (news_id) DESC
LIMIT 0,5

How can I do that?

1 way you can do it is to generate a partitioned row number per user and then select 5 records where RowNumber = 1.

SELECT *
FROM
  (
    SELECT
      d.user_id
      ,d.news_id
      ,d.title
      ,(@rn:= if(@uid = user_id, @rn + 1,
                 if(@uid:=user_id,1,1)
                 )
        ) as RowNumber
    FROM
      Data d
      CROSS JOIN (SELECT @uid:=-1, @rn:=0) vars
    ORDER BY
      user_id
      ,news_id
) t
WHERE
  t.RowNumber = 1
ORDER BY news_id
LIMIT 5;

http://rextester.com/JRIZI7402 - example to show it working

Note you can change the row order by simply changing the ORDER BY statement of the derived table so if you have a column that will signify the latest record eg an identity column or a datetime column you can use that, but user_id must be the first criteria to be partitioned correctly.

Do it from your query.

"SELECT * FROM table GROUP BY user_id ORDER BY news_id DESC LIMIT 5"

well, i think this will achieve what you are after.

select user_id, news_id, title from tableName
   GROUP BY user_id 
   ORDER BY news_id DESC
   LIMIT 0,5

Hope this helps!

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