I have designer and design table
designer has many designs
I want to get all designers with 10 designs for each designer
Is there way I can do it in a single query in either postgresql, mysql
I have designer and design table
designer has many designs
I want to get all designers with 10 designs for each designer
Is there way I can do it in a single query in either postgresql, mysql
 
    
    For best performance in Postgres (not possible in MySQL) use a LATERAL join:
SELECT d.designer, d1.design  -- whatever columns you need
FROM   designer d
LEFT   JOIN LATERAL (
   SELECT *                   -- or just needed columns
   FROM   design
   WHERE  designer_id = d.designer_id
   -- ORDER  BY ???           -- you may want to pick certain designs
   LIMIT  10
   ) d1 ON true
ORDER  BY d.designer_id, d.design_id;  -- or whatever
This gives you 10 designs per designer - or as many as he/she has if there are fewer.
LEFT JOIN LATERAL ... ON true keeps designers in the result that don't have a single design (yet).
You get best performance if you add an ORDER BY clause that matches an existing index on design like:
CREATE INDEX foo ON design (designer_id, design_id)
Then, in the subquery d1 in above query:
...
ORDER  BY design_id
...
Now Postgres can pick the top items from the index directly.
Related answer with more details:
 
    
     
    
    select * from  ( 
    Select row_number() OVER (PARTITION BY a.designer ORDER BY b.design DESC) rn,
        a.* ,b.* 
    from a
    inner join  b
        on a.id = b.id
    ) 
    where rn <= 10
mysql doesn't have window functions, which you need, so this is postgresql.
 
    
    In MySQL, you can make use of user-defined variables to emulate some of the analytic functions available in other databases...
  SELECT v.designer_id
       , v.design_id
    FROM ( SELECT @rn := IF(r.id = @prev_r_id,@rn+1,1) AS rn
                , @prev_r_id := r.id AS designer_id
                , d.id AS design_id
             FROM (SELECT @rn := 0, @prev_r_id := NULL) i
            CROSS
             JOIN designer r
             LEFT
             JOIN design d
               ON d.designer_id = r.id
            ORDER BY r.id, d.id
         ) v 
   WHERE v.rn <= 10
   ORDER BY v.designer_id, v.design_id
You can run just the inline view query (v) to see what that returns. What it does is order the rows by designer_id, and compares the value from the current row to the value from the previous row... if they match, it increments @rn by 1, otherwise, it resets @rn to 1. Net effect is that we get an ascending integer sequence from rn for each designer_id... 1,2,3.
The outer query filters out the rows where rn is greater than 10.
If a given designer has fewer than ten designs, we get fewer than ten rows for that designer.
