如何逐个从数据库返回样本行

时间:2013-05-30 15:15:55

标签: sql asp.net-mvc postgresql sample random-sample

网页应显示PostgreSql数据库中特定产品类别的一个产品图像。 每25秒后,此图像应自动更改为其他图像。 退回的产品可以是随机的或以某种顺序。某些产品可能会丢失,有些产品会重复出现,但标准中的大部分产品都应该退回。 样本检索之间的总可用图像数量可能略有变化

目前使用以下代码,每25秒执行一次。 这需要对数据库进行两次查询:一次查询可能是slwo,第二次查询 单一图像检索。在条件重复的两种情况下,在实际应用中,子句非常大并且更改它需要在两个地方进行更改。

如何改进这一点以便单个查询返回样本? 列类型不能更改,使用自然主键。如果有帮助,可以添加其他列,触发器,索引和序列。

ASP.NET /Mono MVC3,使用了npgsql。

$count = select count(*)
         from products
         where prodtype=$sometype and productid in (select productid from images);

$random = next random integer between 0 .. $count-1;

--  $productsample  is result: desired sample product
$productsample = select product
          from products
          where prodtype=$sometype and productid in (select productid from images)
          offset $random
          limit 1;


create table products ( productid char(20) primary key,
   prodtype char(10) references producttype 
);

create table images(
id serial primary key, 
productid char(20) references products,
mainimage bool
);

2 个答案:

答案 0 :(得分:2)

如果订单中的表达式未编入索引,则order by将始终很昂贵。所以不要订购。相反,在查询中count()执行随机偏移,但一次完成所有操作。

with t as (
    select *
    from
        products p
        inner join
        images i using (productid)
    where
        prodtype = $sometype
)
select *
from t
offset floor(random() * (select count(*) from t))
limit 1

此版本可能更快

with t as (
    select *, count(*) over() total
    from
        products p
        inner join
        images i using (productid)
    where
        prodtype = $sometype
)
select *
from t
offset floor(random() * (select total from t limit 1))
limit 1

答案 1 :(得分:0)

PosgreSQL:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1

这会给你一个随机行。您当然可以在WHERE过滤器中添加回来以确保它是正确的类别。

这样就无需先执行计数;并且还具有让数据库引擎进行选择,减少往返的优势。

注意:对于在其他SQL引擎中寻找方法的人:http://www.petefreitag.com/item/466.cfm