| 0.9 | 1.0 | 1.5.3 | 1.5.4 | 1.5.5 | 2.0 | 2.0.3 | 2.0.4 | 2.1 | 2.5 | 3.0 |
|---|---|---|---|---|---|---|---|---|---|---|
| Да | Да | Да | Да | Да | Да | Да | Да | Да | Да | Да |
Внимание! Почти с каждым новым релизом сервера Firebird в оператор SELECT добавлялась новая возможность или параметр. В связи с этим, смотрите версию сервера напротив описания каждого параметра оператора.
<select statement> ::=
<select expression> [FOR UPDATE] [WITH LOCK]
<select_expression> ::=
<select_expr_body>
[ ORDER BY <sort_value_list> ]
[ ROWS <record_number> [TO <record_number>] ]
<select_expr_body> ::=
{ <query_specification> | <select_expr_body> UNION [DISTINCT | ALL] <query_specification> }
<query_specification> ::=
SELECT
[DISTINCT | ALL]
[FIRST {<record_number> | (:param_recordnumber) } [SKIP <record_number> | (:param_recordnumber) ] ]
<select_list>
FROM <reference_expression_list>
[ WHERE <search condition> ]
[ GROUP BY <group_value_list> ]
[ HAVING <group_condition> ]
[ PLAN <plan_item_list> ]
<select_list> ::=
{ <constant>
| <column_name>[<array_dim>]
| <expression>
| <function> ([<select_list>])
| <UDF> ([<select_list>])
| NULL
| {CURRENT_USER | CURRENT_ROLE | CURRENT_TIMESTAMP | CURRENT_CONNECTION | CURRENT_XXX }
| RDB$DB_KEY
} [COLLATE <collate>] [AS <column_alias_name>]
<reference_expression_list> ::=
{<table name> | <view name> | <procedure name> | <joined table> | <derived table> }
<derived table> ::=
'(' <select expression> ')'
<joined table> ::=
{ <cross_join> | <qualified_join> }
<cross_join> ::=
<reference_expression_list> CROSS JOIN <reference_expression_list>
<qualified_join> ::=
<reference_expression_list> [{INNER | {LEFT | RIGHT | FULL} [OUTER]}] JOIN <reference_expression_list> ON <join condition>
<search_condition> ::=
<val> <operator> { <val> | <singletone_select> }
| <val> [NOT] BETWEEN <val> AND <val>
| <val> [NOT] LIKE <val> [ESCAPE <val>]
| <val> [NOT] CONTAINING <val>
| <val> [NOT] STARTING WITH <val>
| <val> [NOT] IN ( { <val> [,<val> ] | <select expression> } )
| <val> IS [NOT] NULL
| {ALL | SOME | ANY} (<select expression>)
| EXISTS (<select expression>)
| SINGULAR (<select expression>)
| {AND | OR} [NOT] (<search condition>)
<operator> ::=
{ = | < | > | <= | >= | !< | !> | <> | != }
<sort_value_list> ::=
{<column_name> | <column_number | expression> } [COLLATE <collation> ] [ASC[ENDING] | DESC[ENDING] [NULLS {FIRST|LAST}] ] [, <sort_value_list>]
Для передачи параметра в предложения First, Skip и Rows параметр надо заключать в скобки:
select first (:param) <список выбираемых полей> from my_table
Встроенные функции, UDF, CURSOR, INSERT, UPDATE, DELETE, COLLATE, FOR, RDB$DB_KEY, JOIN
LangRef.pdf, Firebird 1.5 Language Reference Update
($firebird)/doc/sql.extension/README.select_expressions.txt
Дискуссия
стоит заметить что ORDER BY может использоваться с параметром DESC
как пример:
Столкнулся с проблемой: <column_alias_name> нельзя напрямую использовать в <search_condition>, то есть запрос: [code]SELECT FIELD1 AS ALIAS_NAME1 FROM TABLE1 WHERE ALIAS_NAME1 = :some_val[/code] вернет ошибку, что поле ALIAS_NAME1 не существует. Насколько я помню, подобные SQL-конструкции срабатывали еще в FoxPro 2.x. FIELD1, в моем случае, динамический. В Firebird нормального решения пока не нашел. Приходится доп.средствами разбирать и править запрос
Может я чего упустил, и все-таки существует волшебная функция поиска поля по алиас-нэйму?
они (алиасы) разве не в другом месте запроса стоят?
SELECT prov_org.number, prov_org.name, oblast1.name_oblast, rayon1.name_rayon, naspunkt1.name_naspunkt , street1.name_street, prov_org.dom_kv, prov_org.inn, prov_org.number_dog, prov_org.sut_dog, result.name_result, prov_org.date_post, s1.fio_access, s2.fio_access, poluch_name»;
Cергей, Вы меня не поняли. Проблему, конечно, я решил, но в функционале это явная брешь. Помимо «FROM table AS t1» (кстати, сам «AS» тут неприменим. Правильно так: «FROM table t1»), существуют алиасы полей: «SELECT field_name AS lfn FROM table t1». Так вот именно этот «lfn» невозможно использовать в конструкции WHERE. У меня задача больно специфичная, выборка полей в зависимости от прав доступа, и я не всегда знаю, какое реальное поле там может находиться. Предрекая критику, скажу: эти запросы кэшируются и переформировываются крайне редко, при изменении структуры БД или изменении прав доступа.
<p> Руслан, есть такое решение: </p> <pre class=«code»> SELECT * FROM ( SELECT field_name AS lfn FROM table t1 ) WHERE ( lfn = '123' ) </pre>
Спасибо, Антон. Свою проблему решил хранимками, сейчас уже переделывать не буду, но Вашу конструкцию протестировал и взял на заметку. Точнее, я знал, что такая существует, но при решении проблемы она в голову не пришла. Результат дискуссии: волшебной функции нет, есть SELECT FROM SELECT :) И всё равно считаю это недоработкой СУБД. Бубен, конечно, вазелином не смазан, но всё же бубен :) Всем спасибо! Вопрос закрыт.
Дело в том, что при выполнение запроса сначала обрабатывается ветвь FROM, затем WHERE и только после этого SELECT. Т.е. Firebird ничего не знает про алиас столбца, если встречает его в WHERE.
Возможно ли в ORDER BY указать список полей для сортировки, переданный во входном параметре? Что-нибудь, типа такого: select * from table1 order by :FSORT где, FSORT = 'field1, field2 desc'
Речь идёт про изменение сортировки для выходного набора записей из хранимой процедуры. При этом сортировкой хочется управлять, передавая в процедуру параметр.
нет так нельзя. или через группу if или через execute statement
Через execute statement сделал, работает. Но меня смущает то, что написано о снижении быстродействия запросов. И всё же, как мне кажется, невозможность использования выражения или числовой переменной для указания сортировки - расходится с документацией.
Да, я согласен, протупил и в переменной нельзя передать СТРОКУ, но зато можно передать НОМЕР выходного столбца для сортировки. И если его явно указать, то работает: select * from table1 order by 1; При этом (тут, в описании <sort_value_list>) явно указано, что можно использовать выражение (expression) для указания номера столбца. И если, к примеру, в переменной :FSORT передать 1, то запрос не будет работать!!! select * from table1 order by :FSORT; Да даже просто, если выражение явное поставить - не работает: select * from table1 order by BIN_OR(0,1);
Добрый день, господа знатоки! Имею firebird 1.5.2, имею запрос
Select * From ( SELECT distinct
c.CLIENT_NAME name, d.Docum_num Num, o.Oper_summa Summa_Peni, o.Oper_date Fakt, max(o2.Oper_date) Pl, (Max(o.Oper_date)- max(o2.Oper_date)) ProsFROM OPER o
inner join Docum d on o.Oper_deb = d.Docum_ID AND o.OPER_TYPE = -301 AND o.OPER_PLAN = 0 inner join Client c on c.Client_ID = d.Docum_Client inner join Oper o2 on o2.oper_deb = d.Docum_ID and o2.oper_plan = 2 and (extract(year from o2.Oper_Date) = extract(year from o.Oper_date)) and (extract(month from o2.Oper_Date) = extract(month from o.Oper_date)) and (extract(day from o2.Oper_Date) <= extract(day from o.Oper_date))WHERE
(OPER_DATE > '31.10.2011') AND (OPER_DATE < '31.12.2011')GROUP BY
c.CLIENT_NAME, d.Docum_num, o.Oper_summa, o.Oper_Date) Peni WHERE Peni.Pros > 0
Выдает ошибку Invalid token. Dynamic SQL error SQL error code =-104 Token unknown -line 2, char 8 SELECT.
Не могу понять в чем проблема. Подскажите пожалуйста.
FB 1.5.X не поддерживает вложенные запросы.
Внутренний запрос сам работает.
Подскажите пожалуйста, раньше работал такой запрос Select num_reestr as num from reestr where num_reestr = 185; Для меня важно чтобы название возвращаемой колонки было num , а возвращается num_reestr; Для подключеня к базе firebird v2.5 использую последний драйвер JDBC (Jaybird-2.2.0JDK_1.7) + java7 Раньше использовал Jaybird-2.1.6JDK_1.6 + java6 В IBexpert все работает.
решил вопрос так (java код): String field_name = rs.getMetaData().getColumnLabel(i); Хотя раньше работал такой код: String field_name = rs.getMetaData().getColumnName(i);.
Неверно указан порядок DISTINCT и FIRST. Указывать нужно сначала FIRST а затем DISTINCT