我有设计师和设计表
设计师有很多设计
我想让所有设计师为每位设计师设计10个设计
我可以在postgresql,mysql
中的单个查询中执行此操作答案 0 :(得分:1)
为了获得 Postgres 的最佳效果(在MySQL中无法实现),请使用 LATERAL
加入:
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
这为每位设计师提供了10个设计 - 如果有更少的设计,则可以为他/她提供多少设计。
LEFT JOIN LATERAL ... ON true
让设计师在结果中保持一个没有单一设计的设计。
如果您添加与ORDER BY
上的现有索引匹配的design
子句,就会获得最佳效果:
CREATE INDEX foo ON design (designer_id, design_id)
然后,在上面查询中的子查询d1
中:
...
ORDER BY design_id
...
现在,Postgres可以直接从索引中选择顶级项目。
相关答案以及更多细节:
答案 1 :(得分:0)
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没有你需要的窗口函数,所以这是postgresql。
答案 2 :(得分:0)
在MySQL中,您可以使用用户定义的变量来模拟其他数据库中可用的一些分析函数......
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
您只需运行内联视图查询(v
)即可查看返回的内容。它的作用是按designer_id
对行进行排序,并将当前行的值与前一行的值进行比较...如果匹配,则将@rn
增加1,否则重置@rn
到1.净效果是我们从rn
得到每个designer_id的升序整数序列... 1,2,3。
外部查询过滤掉rn
大于10的行。
如果给定的designer
少于10 designs
,则designer
的行数少于10行。