1

Тема: Функція максимальна ціна (Оракл)

відобразити найдорощу книгу по кожній тематиці. (Вибірка проводиться з таблиць Книги і Теми)
Даний  код показує тільки одну книгу, найдорощу з усіх книг в таблиці книги.
Наприклад якщо по тематиці Детектив є 10 книг, то функція має поазати найдорощу, якщо в тематиці Роман - 5 книг, так само має показати найдорощу.

create or replace function most_expensive_book
return int is
max_price_by_theme int;
begin
select max(b.PRICE)into max_price_by_theme from BOOKS b, themes t where b.id_theme=t.id_theme;
return max_price_by_theme;
end;

2

Re: Функція максимальна ціна (Оракл)

Ця функія має вертати найдорощу книгу по тематиці. Тематика має задаватись користувачем (Айді тематики).

3

Re: Функція максимальна ціна (Оракл)

задав Айді теми параметром, але функція не працює як потрібно. Вона видає максимальну ціну по всім книгам.

create or replace function most_expensive_book(ID_THEME int)
return int is

max_price_by_theme int;
begin
select max(b.PRICE)into max_price_by_theme from BOOKS b, themes t where b.id_theme=t.id_theme;
return max_price_by_theme;
end;

4

Re: Функція максимальна ціна (Оракл)

Мене трохи плутає ваша нотація. Я завжди роблю, якщо вже на цю тему (не певен, що в ораклі синтаксис саме такий)

CREATE TABLE Themes (
     id INT NOT NULL PRIMARY KEY,
     ...
);

CREATE TABLE Books (
     id INT NOT NULL PRIMARY KEY,
     id_theme INT FOREIGN KEY REFERENCES Persons(id),
     ...
);

Тепер `Таблиця`.id - це id таблиці, а `Таблиця`.id_інша_таблиця - це зовнішній ключ.

Звісно, це вимагає на JOIN-ах дописувати всі імена таблиць; але ваша нотація теж цього вимагає, але нічого не додає.

5

Re: Функція максимальна ціна (Оракл)

то як зробити, щоб виводило максимальну ціну по тематиці?

6

Re: Функція максимальна ціна (Оракл)

Спершу ґуґлити про динамічний sql, тоді підкажу предметніше.

7

Re: Функція максимальна ціна (Оракл)

create or replace function most_expensive_book(ID_THEME int)
return int is
max_price_by_theme int;
begin
select max(b.PRICE)into max_price_by_theme from BOOKS b inner join themes t on (b.id_theme=t.id_theme)
where t.id_theme = ID_THEME;
--select max(b.PRICE)into max_price_by_theme from BOOKS b inner join themes t on(b.id_theme=t.id_theme)and ID_THEME=t.id_theme;
return max_price_by_theme;
end;

помилка:

PL/SQL: ORA-00918: column ambiguously defined

8

Re: Функція максимальна ціна (Оракл)

create or replace function most_expensive_book(ID_THEME int)
return int is
max_price_by_theme int;
begin
select max(b.PRICE)into max_price_by_theme from BOOKS b where  b.id_theme in 
(select t.ID_THEME from THEMES t where b.ID_THEME=t.ID_THEME and b.id_theme = ID_THEME);
return max_price_by_theme;
end;

переробив, але при зміні ID_THEME в параметрах ціна не міняється.

9

Re: Функція максимальна ціна (Оракл)

(select t.ID_THEME from THEMES t where b.ID_THEME=t.ID_THEME and b.id_theme = ID_THEME);

Що ви тут намагаєтеся зробити?

Вибрати t.ID_THEME, такий, що b.ID_THEME=t.ID_THEME і b.id_theme = ID_THEME

Ще раз:

Вибрати A таке, що B=A і B=C

Математика нам каже, що якщо A=B=C, то A=C. Тобто весь цей вираз завжди (ну добре, коли існують A і B, інакше там нічого не знайдеться) буде дорівнювати C. Тобто ID_THEME. Увесь вираз можна скоротити до ID_THEME.

10

Re: Функція максимальна ціна (Оракл)

create or replace function most_expensive_book(ID_THEME int)

Я би тут видозмінив назву вхідного параметру, наприклад THEME_ID, щоб ця назва не збігалася з назвою відповідної колонки.
Тоді нижче відповідно теж би змінив:

... and b.id_theme = THEME_ID);