2013-06-23 29 views
2

我愿做这样的事情:在Firebird中,如何聚合前N行?

CNT=2; 

//[edit] 
select avg(price) from (
    select first :CNT p.Price 
    from Price p 
    order by p.Date desc 
); 

这不起作用,火鸟不允许:cnt作为参数传递给第一位。我需要平均第一个CNT最新价格。数字2发生变化,因此无法进行硬编码。

这可以分解为FOR SELECT循环并在达到计数时中断。那是最好的方法吗?这可以在单个SQL语句中完成吗?

将SQL创建为字符串并运行它也不是最合适的。数据库编译我的SQL语句很重要。

回答

3

您不必使用CTE,你可以直接做到这一点:

select avg(price) from (
    select first :cnt p.Price 
    from Price p 
    order by p.Date desc 
); 
+0

Firebird拒绝使用“令牌未知”并指向变量cnt之前的':'。换句话说,它不接受变量作为“FIRST”的参数。 – jcalfee314

+0

你的例子更好,所以我已经更新了这个问题...... – jcalfee314

+0

':variable'显然只能在PSQL中工作。否则你不能定义变量。或者,您也可以使用基于您的提供商的参数。即在.NET中,您可以编写'select first @cnt ...'并在'FbCommand'中定义参数。 –

1

在计算平均值之前,可以使用CTE(公用表表达式)(请参见http://www.firebirdsql.org/refdocs/langrefupd21-select.html#langrefupd21-select-cte)选择数据。 见下面的例子:

with query1 as (
    select first 2 p.Price 
    from Price p 
    order by p.Date desc 
) 

select avg(price) from query1 
+0

不错的尝试,真的,我真的很享受的热膨胀系数太大。但是,你硬编码的2虽然。我不知道2;它是一个变量。 – jcalfee314