Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Oracle Tutorial.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
401.64 Кб
Скачать

Задача. Сумма зарплат подчиненных.

По таблице kk_employee из задачи “Соединение иерархической таблицы с обычной” составить иерархический запрос, который выдает по каждому сотруднику сумму зарплат его подчиненных а) включая его самого б) не включая его самого.

Потренируемся в определении суммы зарплат подчиненных (включая его самого) для одного конкретного сотрудника с id = 2. Без всяких подзапросов навешиваем на иерархический запрос агрегирующую функцию sum():

select sum(a.wage)

from kk_employee a

connect by prior a.id = a.boss_id

start with a.id = 2;

Теперь используем этот результат в качестве подзапроса в запросе по всем сотрудникам:

select b.id,

b.fio,

(select sum(a.wage)

from kk_employee a

connect by prior a.id = a.boss_id

start with a.id = b.id) as total_wage_sum

from kk_employee b;

К сожалению приходится для каждого сотрудника целиком раскручивать дерево, проходясь по одним и тем же ветвям несколько раз.

Теперь вычтем зарплату самого сотрудника, чтобы подсчитать сумму зарплат его подчиненных, не включая его самого:

select b.id,

b.fio,

(select sum(a.wage)

from kk_employee a

connect by prior a.id = a.boss_id

start with a.id = b.id) - b.wage as total_wage_sum_without_himself

from kk_employee b;

Задача. Простой календарь.

Написать запрос, который выдает 366 строк – дат с 1-янв-2012 до 31-дек-2012.

Воспользуемся иерархическим запросом, соединив dual саму с собой 366 раз:

select to_date('31.12.2011', 'DD.MM.YYYY') + level

from dual

connect by level <= 366;

Такой календарь полезен в быту и народном хозяйстве.

Задача. Детальный календарь.

Создать таблицу-календарь на 2000-2020 годы со следующими полями: дата, день месяца, месяц, год, номер дня недели, день недели, номер недели в месяце, номер недели в году:

Напишем запрос, обратим внимание, что взгляд Oracle на то, как считать номер недели в месяце и номер недели в году, не всем нравится, поэтому предложим еще и альтернативную версию:

select dt,

to_char(dt, 'DD') day,

to_char(dt, 'MONTH') month_code,

to_char(dt, 'YYYY') year,

to_char(dt, 'D') day_of_week,

to_char(dt, 'DAY') day_of_week_code,

to_char(dt, 'W') week_of_month_oracle,

ceil((trunc(dt, 'IW') + 7 - trunc(dt, 'MM')) / 7) week_of_month_alternative,

to_char(dt, 'IW') week_of_year_oracle,

ceil((trunc(dt, 'IW') + 7 - trunc(dt, 'YYYY')) / 7) week_of_year_alternative

from (select to_date('31.12.1999', 'DD.MM.YYYY') + level dt, level lvl

from dual

connect by level <= 7671);

Задача. Календарь с индикаторами выходных дней.

Дана таблица со списком выходных дней 2012 года, в которой учитываются праздники и переносы выходных дней. С помощью иерархического запроса создать календарь на 2012 год со столбцом, представляющим собой индикатор суббот и воскресений, а также столбцом, представляющим собой индикатор нерабочих дней. Индикаторные поля принимают значение 0 или 1.

Изучив постановления правительства, создадим таблицу со списком выходных дней:

create table kk_holidays_list(operdate date);

insert into kk_holidays_list(operdate) values(to_date('01.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('02.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('03.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('04.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('05.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('06.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('07.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('08.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('09.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('14.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('15.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('21.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('22.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('28.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('29.01.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('04.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('05.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('11.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('12.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('18.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('19.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('23.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('25.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('26.02.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('03.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('04.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('08.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('09.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('10.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('17.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('18.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('24.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('25.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('31.03.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('01.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('07.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('08.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('14.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('15.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('21.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('22.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('29.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('30.04.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('01.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('06.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('07.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('08.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('09.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('13.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('19.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('20.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('26.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('27.05.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('02.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('03.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('10.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('11.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('12.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('16.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('17.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('23.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('24.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('30.06.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('01.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('07.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('08.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('14.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('15.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('21.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('22.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('28.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('29.07.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('04.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('05.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('11.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('12.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('18.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('19.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('25.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('26.08.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('01.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('02.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('08.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('09.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('15.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('16.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('22.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('23.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('29.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('30.09.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('06.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('07.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('13.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('14.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('20.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('21.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('27.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('28.10.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('03.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('04.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('05.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('10.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('11.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('17.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('18.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('24.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('25.11.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('01.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('02.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('08.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('09.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('15.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('16.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('22.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('23.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('29.12.2012', 'dd.mm.yyyy'));

insert into kk_holidays_list(operdate) values(to_date('30.12.2012', 'dd.mm.yyyy'));

Соединим простой календарик за 2012 год, указанный в подзапросе q1, со списком выходных kk_holidays_list. Будем использовать left join.

is_weekend = 1 для дней недели номер 6 и 7. is_holiday = 1 для дат из справочника выходных kk_holidays_list:

select dt,

decode(to_char(q1.dt, 'D'), '6', '1', '7', '1', '0') is_weekend,

decode(h.rowid, null, 0, 1) is_holiday

from (select to_date('31.12.2011', 'DD.MM.YYYY') + level dt

from dual

connect by level <= 366) q1

left join kk_holidays_list h

on q1.dt = h.operdate

order by q1.dt;

Сonstraints

В oracle существует возможность накладывать ограничения (constraints) на допустимые значения в полях таблиц. Ограничения можно посмотреть запросом из соответствующей вьюшки словаря данных:

select * from user_constraints; -- констрейнты

В поле constraint_type можно посмотреть тип констрейнта.

На какой-либо боевой базе можно посмотреть, какие они бывают:

select constraint_type, count(1) from user_constraints group by constraint_type order by 2 desc;

Расскажем о 4 типах констрейнтов:

С - check constraints

Этот тип ограничения используют, чтобы ограничить набор допустимых значений поля (или полей) таблицы. Например, создадим таблицу check_tst и ограничение c_check_tst_id на поле id этой таблицы:

create table check_tst (id number);

alter table check_tst add constraint c_check_tst_id check (id >= 0);

При попытке вставить недопустимое значение получим ругательство ORA-02290:

insert into check_tst (id) values (-1);

P - primary keys

Первичные ключи. Первичные ключ - это поле или набор полей таблицы, по значениям которых можно уникальным образом идентифицировать строку. Ни одно из полей первичного ключа не может принимать значения null. Значения первичного ключа не могут повторяться. У таблицы не может быть более одного первичного ключа.

Создадим таблицу регионов:

create table ref_test_regions(region_id number, region_name varchar2(50));

Создадим первичный ключ на поле ref_test_regions.region_id. Опция "using index" позволяет одновременно проиндексировать поле, составляющие первичный ключ:

alter table ref_test_regions add constraint pk_ref_test_regions primary key (region_id) using index;

Вставим в таблицу одну строку:

SQL> insert into ref_test_regions(region_id, region_name) values(1, 'Москва');

1 row inserted

При повторной попытке вставить такое же значение первичного ключа получаем ошибку:

SQL> insert into ref_test_regions(region_id, region_name) values(1, 'Москва');

ORA-00001: unique constraint (STORAGE.PK_REF_TEST_REGIONS) violated

Дропнуть первичный ключ можно командой

alter table ref_test_regions drop primary key;

или

alter table ref_test_regions drop constraint pk_ref_test_regions;

R - reference constraints (foreign keys)

Это ограничения ссылочной целостности между таблицами. Если такое ограничение создано, то нельзя вставить в поле значение, которого нет в первичном ключе ссылающейся таблицы.

Создадим таблицу клиентов:

create table ref_test_clients(client_id number, region_id number);

Создадим в таблице клиентов foreign key на справочник регионов:

alter table ref_test_clients add constraint fk_ref_test_clients_region_id foreign key (region_id) references ref_test_regions (region_id);

Вставим в таблицу строку со значением region_id, присутствующим в справочнике регионов ref_test_regions:

SQL> insert into ref_test_clients(client_id, region_id) values(1, 1);

1 row inserted

Попытка вставить в таблицу строку со значением region_id, отсутствующим в справочнике регионов приводит к ошибке:

SQL> insert into ref_test_clients(client_id, region_id) values(1, 222);

ORA-02291: integrity constraint (STORAGE.FK_REF_TEST_CLIENTS_REGION_ID) violated - parent key not found

U - unique constraints

Ограничения уникальности. Значения поля (или набора полей) должны быть уникальными в рамках таблицы. В отличии от первичного ключа unique constraints позволяют вставлять значения null, а также у таблицы может быть несколько unique constraints.

Создадим таблицу студентов

create table test_students(student_id number, student_ticket_number varchar2(20), passport_series varchar2(20), passport_number varchar2(20));

Создадим 2 ограничения уникальности на эту таблицу. Опция "using index" позволяет одновременно проиндексировать поля, на которые накладывается констрейнт.

alter table test_students add constraint uc_test_students1 unique (student_ticket_number) using index;

alter table test_students add constraint uc_test_students2 unique (passport_series, passport_number) using index;

Вставим данные:

SQL> insert into test_students(student_id, student_ticket_number, passport_series, passport_number) values(1, '29740497', '28 02', '485892');

1 row inserted

SQL> insert into test_students(student_id, student_ticket_number, passport_series, passport_number) values(2, '29723789', '28 02', '623784');

1 row inserted

SQL> insert into test_students(student_id, student_ticket_number, passport_series, passport_number) values(3, '29740497', '28 02', '485892');

ORA-00001: unique constraint (STORAGE.UC_TEST_STUDENTS1) violated

SQL> insert into test_students(student_id, student_ticket_number, passport_series, passport_number) values(4, '29719109', '28 02', '623784');

ORA-00001: unique constraint (STORAGE.UC_TEST_STUDENTS2) violated

Констрейнты можно выключать (DISABLE), включать обратно (ENABLE), можно совсем удалять (DROP):

alter table test_students disable constraint uc_test_students1;

alter table test_students enable constraint uc_test_students1;

alter table test_students drop constraint uc_test_students1;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]