Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / помогите с запросом / 17 сообщений из 17, страница 1 из 1
15.08.2007, 12:40
    #34729053
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
drop table t1;
create table t1
(
a int
);
insert into t1 values ( 1 );
insert into t1 values ( 2 );
insert into t1 values ( 3 );

create or replace function fn1(in a int, out b int, out c int)
as
$$
begin
  select (a*a), (a*a*a) into b, c;
end;
$$
language 'plpgsql';
Надо сделать выборку из таблицы связав с функцией, чтобы получить следующий результат (3 поля)
Код: plaintext
1.
2.
 1    1    1 
 2    4    8 
 3    9    27 
...
Рейтинг: 0 / 0
15.08.2007, 13:04
    #34729180
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Вот так надо:t1.afn1(a).bfn1(a).c1112483927
...
Рейтинг: 0 / 0
15.08.2007, 13:55
    #34729402
Serik Akhmetov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create or replace function fn1(in a int, out b int, out c int)
returns setof record
as
$$
begin
    b := a*a;
    c := a*a*a;
    return next;
    return;
end;
$$
language 'plpgsql';

Код: plaintext
1.
2.
select t1.a, f.b, f.c
from t1
left join fn1(t1.a) f on ( 1 = 1 );
...
Рейтинг: 0 / 0
15.08.2007, 14:34
    #34729576
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Код: plaintext
1.
2.
3.
4.
select t1.a, f.b, f.c
from t1
left join fn1(t1.a) f on ( 1 = 1 );

ERROR: missing FROM-clause entry for table "t1"
...
Рейтинг: 0 / 0
15.08.2007, 14:57
    #34729653
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
если с псевдонимом получим другую ошибку
Код: plaintext
1.
2.
3.
4.
select t.a, f.b, f.c
from t1 t
left join fn1(t.a) f on ( 1 = 1 );

ERROR: relation "t" does not exist
...
Рейтинг: 0 / 0
15.08.2007, 15:20
    #34729747
Serik Akhmetov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
точно, не работает, можно так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
CREATE OR REPLACE FUNCTION fn1(IN a integer, OUT b integer, OUT c integer) AS
$BODY$
begin
    b := a*a;
    c := a*a*a;
    return;
end;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
Код: plaintext
1.
2.
3.
select t1.a,
(select b from fn1(t1.a)) as b,
(select c from fn1(t1.a)) as c
from t1
...
Рейтинг: 0 / 0
15.08.2007, 15:30
    #34729799
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
спасибо, а можно по другому? слишком много селектов, а таблицы и функции не такие маленькие как тесте.
...
Рейтинг: 0 / 0
15.08.2007, 15:59
    #34729932
v0v4ik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
1. Если логика функции не зависит от остальных данных базы, то лутше перенести алгоритм функции на клиент.
2. Если вычислене полей a и b независимы, то имеет смысл разделить функцию на две каждая возвращает a и b соответсивенно. Можно будет писать
select
fn1(t1.a)) as a,
fn1(t1.a)) as b
from t1

так как

select t1.a,
(select b from fn1(t1.a)) as b,
(select c from fn1(t1.a)) as c
from t1

удваивает расчеты

3. Есть смысл в функции возвращать расчетные поля + поля таблици
select
a,
b,
c
...
from fn1
as
....
...
Рейтинг: 0 / 0
15.08.2007, 16:05
    #34729955
v0v4ik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Опечатка, я имел в виду
fn1(t1.a) as a,
fn2(t1.a) as b
from t1
...
Рейтинг: 0 / 0
15.08.2007, 16:59
    #34730213
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
v0v4ik1. Если логика функции не зависит от остальных данных базы, то лутше перенести алгоритм функции на клиентзависит
v0v4ik2. Если вычислене полей a и b независимы, то имеет смысл разделить функцию на две каждая возвращает a и b соответсивеннозависимы, сейчас выходных параметоров 8, будет больше
v0v4ik3. Есть смысл в функции возвращать расчетные поля + поля таблицинет. эта функция выводит общую информацию о каждой записи(формируется из нескольких таблиц), которая также формируется из кучи связанных таблиц. раньше на клиенте было много гридов, в которых разобраться стало проблематично. пэйжконтролы и другие контролы не спасают, да и место на формах уже нету. дизайнер из меня никакой, а юзер хочет видеть все и сразу(не обсуждается). этот запрос экономит половину формы. надо думать над индексами ибо сейчас запрос с кучей селектов выполняется от 20 сек.
...
Рейтинг: 0 / 0
15.08.2007, 19:06
    #34730661
v0v4ik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
непонимайу
v0v4ik3. Есть смысл в функции возвращать расчетные поля + поля таблицинет. эта функция выводит общую информацию о каждой записи(формируется из нескольких таблиц), которая также формируется из кучи связанных таблиц. раньше на клиенте было много гридов, в которых разобраться стало проблематично. пэйжконтролы и другие контролы не спасают, да и место на формах уже нету. дизайнер из меня никакой, а юзер хочет видеть все и сразу(не обсуждается). этот запрос экономит половину формы. надо думать над индексами ибо сейчас запрос с кучей селектов выполняется от 20 сек.
Вот именно. Если вы вызываете на каждый столбец одну и ту же функцию, то вычисляете одно и тоже n раз! Джоинить функцию тоже не стоит - индекс по ней не построится нормально в вашем случае. Каждий селект - вызов функции для всех записей.
Помоему вариант 3 - это как раз ваш случай. Это будет самый быстрый и удобный вариант(если правильно написать). Что вас в нем конкретно не устраивает?
...
Рейтинг: 0 / 0
15.08.2007, 20:03
    #34730761
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
v0v4ik Если вы вызываете на каждый столбец одну и ту же функцию, то вычисляете одно и тоже n раз!нет. на запись.
v0v4ik Что вас в нем конкретно не устраивает?может быть не правильно понял. чем отличается "select(view)+function(много селектов)" от "function(select(view)+много селектов)"? кстати были бы индексы на вью...
...
Рейтинг: 0 / 0
15.08.2007, 20:17
    #34730777
v0v4ik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Если вы напишете типа
Код: plaintext
1.
2.
3.
4.
select t1.a,
(select b from fn1(t1.a)) as b,
(select c from fn1(t1.a)) as c
from t1
то функция выполнится 2 раза, хотя она вычысляет за раз все что нужно. В случае с процедурой такого не будет.

Это вы имеете в выду под "select(view)+function(много селектов)"?
...
Рейтинг: 0 / 0
16.08.2007, 06:49
    #34731094
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
v0v4ikЭто вы имеете в выду под "select(view)+function(много селектов)"?да. ясно.
...
Рейтинг: 0 / 0
16.08.2007, 10:27
    #34731436
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
v0v4ikЕсли вы напишете типа
Код: plaintext
1.
2.
3.
4.
select t1.a,
(select b from fn1(t1.a)) as b,
(select c from fn1(t1.a)) as c
from t1
то функция выполнится 2 раза, хотя она вычысляет за раз все что нужно. В случае с процедурой такого не будет.
это не очевидно:

авторA STABLE function cannot modify the database and is guaranteed to return the same results given the same arguments for all rows within a single statement. This category allows the optimizer to optimize multiple calls of the function to a single call. In particular, it is safe to use an expression containing such a function in an index scan condition. (Since an index scan will evaluate the comparison value only once, not once at each row, it is not valid to use a VOLATILE function in an index scan condition.)
,но, естественно, все надо тестировать на живых примерах.
...
Рейтинг: 0 / 0
16.08.2007, 10:40
    #34731483
Funny_Falcon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
есть такой грязный хак:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
drop table t1;
create table t1
(
a int
);
insert into t1 values ( 1 );
insert into t1 values ( 2 );
insert into t1 values ( 3 );

create or replace function fn1(in a int, out b int, out c int)
as
$$
begin
  select (a*a), (a*a*a) into b, c;
end;
$$
language 'plpgsql';
Код: plaintext
1.
2.
3.
4.
5.
select a, (fn).* from (
select a, fn1(a) as fn from t1
union all
select NULL, NULL where false
) t
UNION ALL заставляет "заморозить" результат вычисления fn1(a), и по-этому при применении ().* повторных вычислений не происходит.
В версии 8.3 обещают volatile функции вычислять один раз. Поживем, увидем.
...
Рейтинг: 0 / 0
28.05.2008, 11:41
    #35339561
непонимайу
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Funny_FalconВ версии 8.3 обещают volatile функции вычислять один раз. Поживем, увидем.как сейчас? в доке толи не нашел, то ли не понял.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / помогите с запросом / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]