tags:

views:

78

answers:

4

Hi, I have this table:

id
feed_id
...

Let's say that I have 500 rows and I want to select 3 entries for each feed_id? And 50 as total limit.

How to write this SQL?

+2  A: 

Have you tried using a subselect and limit?

Something like

SELECT  *
FROM    Table t
WHERE   ID IN (SELECT ID FROM @Table WHERE FEED_ID = t.FEED_ID LIMIT 3)
LIMIT 500
astander
i don't think this will work as the subselect (SELECT ID FROM @Table WHERE FEED_ID = t.FEED_ID LIMIT 3)will return only three id's of 1st FEED_ID
Salil
You have to take into account that this is done in a sub select in the where clause, so it will be the 1st 3 **PER** feedid
astander
This won't work. MySQL doesn't support LIMITS in sub-queries, unfortunately.
Marc B
Keyne
Bummer :( I was thinking that was a really slick way to solve this.
OMG Ponies
+3  A: 

Use:

SELECT x.feedid
  FROM (SELECT t.feedid,
               CASE WHEN @feed != t.feedid THEN @rownum := 1 ELSE @rownum := @rownum + 1 END AS rank,
               @feed := t.feedid
          FROM TABLE t
          JOIN (SELECT @rownum := NULL, @feed := 0) r
      ORDER BY t.feedid) x
 WHERE x.rank <= 3
 ORDER BY x.feedid
 LIMIT 50

What's not clear is the details of what you want returned - all the rows in your table, or just the feedid.

OMG Ponies
This works for me, but rows with feed_id = 1 doesn't appear. Am I doing something wrong?
Keyne
@Keyne: There's nothing in the query to exclude a feedid - are you sure there are records for the id value? The next thing I'd look at is if you forgot the ORDER BY - it's absolutely important to the query.
OMG Ponies
Actualy there's nothing with feed_id 1, the problem is with the first row. For instance, I've deleted all rows with feed_id = 1 and when I run the query again, feed_id 2 doesn't show up, which is the first in the rowset.
Keyne
I've solved this changing this line:JOIN (SELECT @rownum := NULL, @feed := 0) rWhen @feed := 0 works as expected.Thank you anyway!
Keyne
@Keyne: Weird - guess the data type really matters. Huh, never experienced that - glad to hear you figured it out.
OMG Ponies
@OMG-Ponies: If I need to order by date, how to keep this working? I'm with a related problem where I have to select just one for each author_id, but ordering by date. Can you help me? http://stackoverflow.com/questions/3886070/how-to-change-this-sql-so-that-i-can-get-one-post-from-each-author
Keyne
A: 

In transact SQL you would use the TOP statement, not sure if that applies here ...

James Westgate
A: 

You can do this with help of stored procedure.

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_feed`()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE a INT;
DECLARE cur1 CURSOR FOR SELECT id FROM test.id LIMIT 50;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
REPEAT
FETCH cur1 INTO a;
    IF NOT done THEN
        SELECT * FROM feed_id WHERE id=a LIMIT 3;               
    END IF;
UNTIL done END REPEAT;
CLOSE cur1;

END$$
DELIMITER;
Veer