2013-06-23 6 views
2

Я хотел бы сделать что-то вроде этого:В Firebird, как собрать первые N строк?

CNT=2; 

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

Это не работает, Firebird не позволяет :cnt в качестве параметра FIRST. Мне нужно усреднить первые цены на 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 отклоняет это с помощью «Token unknown» и указывает на ':' перед переменной cnt. Другими словами, он не принимает переменную как параметр 'FIRST'. – jcalfee314

+0

Ваш пример лучше, поэтому я обновил вопрос ... – jcalfee314

+0

': variable' будет работать только в PSQL, очевидно. Иначе вы не можете определить переменную. Или, альтернативно, вы можете использовать параметры на основе вашего провайдера. То есть в .NET вы можете написать 'select first @cnt ...' и определить параметр в' FbCommand'. –

1

Вы можете использовать CTE (Common Table Expression) (см. 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