Ответы пользователя по тегу Oracle
  • Как вывести все client_id, которые за весь срок кредита не совершали просрочек?

    Я бы попробовал как-нибудь вот так:
    select *
      from clients c
     where exists (
     select null
              from (select abs(principal - lag(principal) over(partition by client_id order by report_date)) diff 
                      from principals p
                     where p.client_id = c.client_id
                     )
             where diff < c.payment_need
                and diff is not null)

    Ключевое в этом запросе lag и exists. Exists должен искать до первого найденного несоответствия, что в среднем ускоряет выборку, а lag -значение по прошлому месяцу.
    Ответ написан
    Комментировать
  • Как в Oracle или Teradata разбить все строки таблицы на N равновеликие СЛУЧАЙНЫЕ выборки?

    select t1. *, ntile(N) over (order by dbms_random.random) nbatch  from t1

    А дальше выбираете нужные части nbatch.
    ntile в Oracle используется для построения гистограмм, поэтому +/- должен работать быстро.
    Ответ написан
    Комментировать
  • Как в строку вставить переменную динамический sql oracle?

    Здравствуйте. В части запроса over(... должны быть либо over(), либо over (partition by...), либо over( order by...).
    У вас получился over ( "значение из group_level.partition_column;
    ")... так не получится- синтаксис аналитических функций другой:
    https://docs.oracle.com/cd/B19306_01/server.102/b1...
    Ответ написан
    Комментировать
  • Подготовка к курсам DBA Oracle. Где взять учебный материал?

    Плохо ищите наверное.
    Я бы вам посоветовал почитать Т. Кайта, Д. Куна isbn= 978-5-907114-89-0, если у вас есть опыт работы с этой БД, хотя мне кажется и без опыта можно разобраться, тем более она на русском. Как прочитаете и поймете хотя бы до главы о типах данных, к этому времени у вас должен быть очень не плохое представление о БД, дочитывайте и параллельно ищите мануал по Data_Pump и RMAN и по-практикуйтесь в восстановлении и бэкапировании БД. И учитесь пользоваться документацией на сайте- лучше ее врятли найдете.
    А дальше, сами...
    Ответ написан
    Комментировать
  • В чем преимущество Oracle перед другими СУБД?

    На ваш вопрос невозможно корректно ответить. Каждая СУБД обладает своими архитектурными особенностями и по сути является платформой, т.е. многие полезные вещи уже реализованы. Т.е. можно сравнивать две конкретные СУБД и рамках решения конкретной задачи. Как СУБД для ИС уровня предприятия, Oracle очень хороший выбор, т.к. обычно в таких системах нагрузка 50 на 50(50 запись\50 чтение). И в силу архитектурных особенностей Oracle(реализация транзакций и блокировок) справляется с такой эксплуатацией на ура. Плюс БД еще надо администрировать, заботиться о сохранности данных после сбоя(бэкапирование), туча функций и объектов для реализации бизнес-логики .... короче много всего что нужно делать, и это уже реализовано в Oracle. И как бонус, Oracle более лоялен к рукожопости разработчиков, которые считают, что все БД одинаково работают и устроены. Если данных много и надо быстро их обрабатывать, можно посмотреть в сторону Exadata. Более подробно об особенностях можно почитать в документации. А во всем остальном нужно смотреть под конкретную задачу. Самый большой минус- это стоимость.
    З.Ы.: И от себя лично добавлю, на заре карьеры я работал с MS SQL и возненавидел эту СУБД, как раз из-за реализаций транзакций и блокировок, и помогли мне в этом прежние разработчики. В MS SQL блокировки на уровне строк, но реализованы в общем пуле- общий пулл блокировок- это минус скорость(общий пулл надо блокировать, для записи или чтения этих блокировок) и плюс память. И чтобы не загружать особо сервер, прежние разрабы реализовали логику так, что процесс проходил мелкими транзакциями, конечно с коммитами. И были такие прецеденты, что данные удалились, а в другую таблицу не встали из-за ошибки в приложении. Потом дедлоки, это вообще отдельная тема, и приходилось разруливать изменением структуры данных, чтобы пользователи работали, только со своими данными. Короче вспоминаю, как страшный сон. Зато при разработке другой ИС где было решение взять Oracle как СУБД, через призму прошлого опыта, для меня было большое открытие, что там не будет такого гемороя, как с MS SQL. Конечно, может быть MS SQL сейчас сильно изменился в лучшую сторону, но осадочек у меня остался.
    Ответ написан
    Комментировать
  • Создать триггер для вставки в view?

    Чтобы у вас заработал данный триггер, как минимум вам нужно перечислить во вью обязательные поля. Т.е. из stations нужно добавить 2 st_id(первичные ключи). А все остальное можете взять из документации https://docs.oracle.com/cd/B19306_01/server.102/b1... в примерах.
    Ответ написан
    Комментировать
  • PL SQL: нужно заменить хранимую функцию на JOIN. Как это оптимально сделать?

    Добрый день, Дмитрий Митяев.
    Если я правильно понял проблему, то можно воспользоваться cte и join.
    with v_idusr_tbl as 
    (
    select distinct first_value(coj.id_new_owner)over(partition by coj.ceid order by coj.begin_date desc) id_new_owner
     from tver.coj
    where coj.ceid=p_ceid
      and trunc(p_date) between trunc(coj.begin_date) and trunc(coj.end_date)
    )
    , tbl_second_group as (
    select distinct first_value(g.name)over(partition by cuj.idusr order by cuj.begin_date desc) name
    , cuj.idusr
                 from tver.ce_usrgroup_jnl cuj,
                      kollecto.groups g,
                      v_idusr_tbl q
                where cuj.idgrp=g.idgrp
                  and g.unique_flag=1
                  and (g.name like 'Legal%' or g.name like 'Field%')
                  and cuj.idusr=q.id_new_owner
                  and trunc(p_date) between trunc(cuj.begin_date) and trunc(cuj.end_date)
    )
    , tbl_first_group as (
    select distinct first_value(g.name)over(partition by cuj.idusr order by cuj.begin_date desc) name
             from tver.ce_usrgroup_jnl cuj,
                  kollecto.groups g,
                  v_idusr_tbl q
            where cuj.idgrp=g.idgrp
              and g.unique_flag=1
              and (g.name like 'Legal%' or g.name like 'Field%')
              and cuj.idusr=q.id_new_owner
              and trunc(p_date)<=trunc(cuj.begin_date)
              and 0 = (select count(1) from tbl_second_group) /*Если в tbl_second_group ничего нет, то выбираем. 
              Скорее всего, это условие будет выполнено в конце при выполнении запроса, я не придумал способ засунуть в секцию from или exists, чтобы он вообще не выполнялся в случае непустого tbl_second_group*/
    )
    
    , tbl_legal_group as (
    select name from tbl_second_group 
    union all
    select name from tbl_first_group 
    )
    select name into v_legalgroup from tbl_legal_group /*Вставляем в переменнную*/
    Ответ написан
    Комментировать
  • Как развернуть значения колонки таблицы в одно поле в PL/SQL?

    Easy:
    with function f (p_login varchar2) return varchar2
    is
    l_retval varchar2(32000);
    begin
    for x in (select id from t where login = p_login)
    loop
     l_retval:= l_retval||'|'||x.id;
    end loop;
    return l_retval;
    end;
    select plogin, f(plogin) from (
    select distinct login as plogin from t
    )
    /

    Пример выше подойдет только с версии 12 с. Но суть не меняется, оформите в функцию по примеру f.
    Ответ написан
    Комментировать
  • Скрипт переноса данных из одной таблицы в другую?

    Воспользуйтесь оператором merge: https://docs.oracle.com/cd/B28359_01/server.111/b2...
    как пример, table1(таблица источник) и table2(таблица приемник):
    merge into table2 t2
    using table1 t1
    on (t1.name_id = t2.name_id)--условие объединения
    when not matched then insert (t2.name_id) values (t1.name_id);
    merge into table2
    Ответ написан
    Комментировать
  • Как сделать агрегацию с окном "внахлест"?

    Если я правильно понял задачу, то есть в SQL оконные функции LAG и LEAD, погуглите их.
    Ответ написан
  • Как запретить передавать пустые агрументы в процедуру?

    Первое значение в raise_application_error- должен быть из диапазона пользовательских ошибок:
    PROCEDURE null_args_testing(arg IN VARCHAR2) IS
    BEGIN
    if arg is null then
    raise_application_error(-20101, 'Значение не может быть NULL');
    end if;

    NULL;
    END;
    Еще можно вот так, если нужна более сложная логика:
    PROCEDURE null_args_testing(arg IN VARCHAR2) IS
    p_is_null exception;
    BEGIN
    if arg is null then
    raise p_is_null;
    end if;

    exception
    when p_is_null then
    /*логика обработки*/
    raise;/*процедура завершается*/
    END;
    Ответ написан
    Комментировать
  • Временная метка при запросе в базу, как реализовать?

    Если под "каждый запрос начинался с того момента когда был запущен предыдущий" подразумевается, что необходимы данные на конкретный период времени, т.е. не учитывая изменения в таблице с указанного времени, то можно воспользоваться ретроспективной областью памяти(https://docs.oracle.com/cd/B14117_01/appdev.101/b1... Пример:
    SELECT * FROM employee AS OF TIMESTAMP
    TO_TIMESTAMP('2003-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')
    WHERE name = 'JOHN';
    Т.е. запрос к таблице -SELECT * FROM employee
    передаем метку scn - AS OF TIMESTAMP TO_TIMESTAMP('2003-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')
    условие- WHERE name = 'JOHN';
    Перед выполнением первого запроса сохраняем метку времени и вставляем таким образом во все запросы.
    Если разница в долях секундах приемлема, то можно создать курсоры подряд ко всем интересующим таблицам
    т.е.
    declare
    х1 refcursor;
    х2 refcursor;
    ...
    begin
    open х1 for select * from t1;
    open х2 for select * from t2;
    ....
    end;
    Затем при работе курсоры будут выводить данные с разницей в доли секунд.
    Ответ написан