Често се случва да се налага да пишем един и същи SELECT. Например всички служители, които имат кредити. Може би е добре тази заявка да бъде записана някъде, а още по-добре е да може да я достъпваме и използваме сякаш резултатът от нея е истинска таблица.
В MySQL изгледите (view) представляват таблици, получени в резултат от SELECT заявки, съхранени с определено име в базата данни.
Синтаксис:
CREATE VIEW <име> (имена на колони)
AS SELECT <имена на колони> … ;
Можете да пропуснете (имена на колони), така ще участват всички колони, които участват и в select.
Например в предна статия търсехме списък с имената на учениците и класовете им, както и номера (id) на групата в която тренират за всички ученици, които тренират в понеделник от 08:00 и са при треньор с име „Иван Тодоров Петров“, но само за групите му по футбол.
Нека по този select да създадем view:
create view footbalGroupsOfIvPetrov AS SELECT students.name, students.class, sportgroups.id FROM students JOIN sportgroups ON students.id IN ( SELECT student_id FROM student_sport WHERE student_sport.sportGroup_id = sportgroups.id ) WHERE sportgroups.id IN( SELECT sportgroup_id FROM student_sport WHERE sportGroup_id IN( SELECT id FROM sportgroups WHERE dayOfWeek = 'Monday' AND hourOfTraining = '08:00:00' AND coach_id IN( SELECT id FROM coaches WHERE name = 'Иван Тодоров Петров' ) AND sport_id =( SELECT id FROM sports WHERE name = 'Football' ) ) );
Можете да видите всички изгледи:
Можете да третирате изгледа като нормална таблица, но с някои особености, разбира се.
SELECT * FROM footbalgroupsofivpetrov;
- Ако във вложения оператор SELECT участват ORDER BY, GROUP BY, HAVING, DISTINCT и UNION, то ако ги използвате, полученото VIEW става необновяемо (read – only), защото данните в него ще са обобщени и промените върху тях няма как да се отразят върху реалните таблици. Такова VIEW е много удачно да наричаме “изглед“, защото то ще става само за четене(заявки SELECT).
- Важно е да има съответствие между върнатите колони от оператора SELECT и изброените след името на VIEW.
- Можем да изпълняваме и заявки от тип INSERT, UPDATE и DELETE – те ще бъдат трансформирани автоматично от системата за управление на бази данни .
- Използването на INSERT, UPDATE и DELETE през VIEW не се препоръчва!
- Най-често VIEW се използва „само за четене“ и съответно потребителите се рестриктират да имат само права SELECT върху тези таблици.
За да изтриете view използвайте :
DROP VIEW <име> CASCADE;
- Ключовата дума CASCADE означава, че ако има производно на това VIEW (т.е. VIEW създадено чрез изтриваното VIEW), то също ще бъде изтрито. Съществува синтактично, но не работи функционално, което означава. че в други СУБД работи и е добре да го знаете.
- Алтернативата е с ключова дума RESTRICT, където ако има производно VIEW, то ще бъде върната грешка.
- По принцип не е добра идея да създавате производни едни на други изгледи.
- Стойността по подразбиране на DROP VIEW e CASCADE.
За за изпълнявате INSERT зявки върху VIEW, трябва в INSERT да поставите всички колони от дадената таблица, чиито стойности са NOT NULL.
За да може да направите едно view да бъде updatable, то трябва да спазите следните правила:
Вашият изглед не трябва да съдържа нито едно от долуизброените:
- Агрегатна функция
- DISTINCT
- GROUP BY клауза.
- HAVING клауза.
- UNION или UNION ALL клауза.
- Left join или outer join.
- Подзаявка в SELECT или в WHERE клауза, която да извлича информация от таблица, която се споменава във FROM клаузата на същата заявка.
- SELECT, който извежда информация от друго non-updatable view във FROM клаузата си.
Даниел Джолев
Задачи от упражнение:
1.SELECT students.name, students.class, students.phone
FROM students
JOIN student_sport on students.id = student_sport.student_id
join sports on sports.id = student_sport.sportGroup_id
where sports.name =’Football’;
2.SELECT coaches.name
From coaches
Join sportgroups on coaches.id = sportgroups.coach_id
JOIN sports on sports.id = sportgroups.sport_id
WHERE sports.name = ‘Volleyball’;
3.SELECT coaches.name, sports.name
From coaches
JOIN sportgroups on coaches.id = sportgroups.coach_id
join sports on sports.id = sportgroups.sport_id
JOIN student_sport on sportgroups.id = student_sport.sportGroup_id
JOIN students on students.id = student_sport.student_id
WHERE students.name=’Iliyan Ivanov’;
4.SELECT sportgroups.id, COUNT(*)
from sportgroups
join student_sport on student_sport.sportGroup_id= sportgroups.id
Group by sportgroups.id;
5.SELECT SUM(paymentAmount)
from taxesPayments join students
on taxesPayments.student_id = students.id
join sportgroups
on taxespayments.group_id= sportGroups.id
join coaches
on sportGroups.coach_id = coaches.id
WHERE year = ‘2016’
and coaches.egn = ‘7509041245’
and taxespayments.paymentAmount > 700
Group by month;
В примера за групите по футбол на Иван Петров не се ли прави излишен селект?
Това е моето решение и работи:
create view footbalGroupsOfIvanPetrov
AS
SELECT students.name, students.class, sportgroups.id
FROM students JOIN sportgroups
ON students.id IN (
SELECT student_id
FROM student_sport
WHERE student_sport.sportGroup_id = sportgroups.id
)
WHERE sportgroups.dayOfWeek = ‘Monday’
AND sportgroups.hourOfTraining = ’08:00:00′
AND coach_id IN(
SELECT id
FROM coaches
WHERE name = ‘Иван Тодоров Петров’
)
AND sport_id =(
SELECT id
FROM sports
WHERE name = ‘Football’
);
Здравейте,
Правилна ви е заявката. Има различни варианти за решение на задачата. В зависимост от обемите данни и степента на нормализация на базата, различните решения могат да дадат по-добър или по-лош резултат.