如果我理解得很好——你需要n
图像。如果可能的话,来自不同的产品。否则,可以接受来自同一产品的多个图像作为后备。
从现在开始,我能想到的唯一解决方案是构建一个临时表,其中包含编号的行,例如每个产品的“顶部”将有一个“图像” - 并与其余图像一起归档。
构建该表后,您的查询只是一个SELECT ... LIMIT n
.
这将执行得非常糟糕——如果您选择受启发的解决方案——您应该离线或按计划合并图像表。
见http://sqlfiddle.com/#!2/81274/2
--
-- test values
--
create table P (id int, title char(20));
insert into P values
(1, "product 1"),
(2, "product 2"),
(3, "product 3");
create table I (pid int, filename char(40));
insert into I values
(1, "image p1-1"),
(1, "image p1-2"),
(3, "image p3-1"),
(3, "image p3-2"),
(3, "image p3-3");
--
-- "ordered" image table
--
create table T(n int primary key auto_increment not null,
filename char(20));
--
-- consolidate images (once in a while)
--
delete from T;
insert into T(filename)
select filename from I group by pid;
insert into T(filename)
select filename from I order by rand();
--
-- do the actual query
--
select * from T limit n;
编辑这是一个完全不同的想法。不使用合并表/视图——因此这可能被视为更好:
http://sqlfiddle.com/#!2/57ea9/4
select distinct(filename) from
(select 1 as p, filename from I group by pid
union (select 2 as p, filename from I order by rand() limit 3)) as T
order by p limit 3
这里的关键点是我不必真正“编号”行。只是为了跟踪哪些行来自第一行SELECT
。这就是 的目的p
。为简单起见,我将两个LIMIT
子句设置为相同的值。我认为您不必“优化”该部分,因为收益会非常小-而且ORDER BY RAND()
太糟糕了,您不必在这里考虑“表演”;)
请注意,我没有完全测试过这个解决方案。让我知道是否有一些不工作的极端情况(好吧..任何情况)。