SQL в вопросах и задачах
.pdf61
ему з нач ение UNKNOWN. Поэтому рез ульта те в ып олнения п од з ап роса не буд ет п олуч ено ни од ного з нач енияи п од з ап рос п римет з нач ениело ж ь. Э то в св ою оч еред ьсд елает NOT EXISTS истинным, и, след ов ательно, строка с
NULL з нач ением п оле RATING п оп а д ет в ыход ные д а нные. |
По смыслу |
з ап роса такой рез ультат яв ляется неп рав ильным, так как на |
са мом д еле |
рейтинг унив ерситета, оп исыв аемого д анной строкой может бытьи больше
рейтинга какого-либо москов ского |
унив ерситета (он п росто неиз в естен). |
У каз анна яп роблема св яз а на с тем, |
ч то з на ч ениеEXISTS в сегд а п р инимает |
з нач енияи ст и на или ло ж ь, и никогд а – UNKNOWN. Э то яв ляетсяд ов од омд ля |
|
исп ольз ов анияв таких случ аях оп ер атора ANY в место EXISTS. |
2.14. И спол ь з ование COUNT вм ест о EXISTS
При отсутств ии NULL-з нач ений оп ера тор EXISTS может быть исп ольз ов ан в место ANY и ALL. Такжев место EXISTS и NOT EXISTS могут бытьисп ольз ов а ны тежесамыеп од з а п росы, но с исп ольз ов анием COUNT(*) в п ред ложении SELECT. Н а п ример, з ап рос
SELECT *
FROM UNIVERSITY A
WHERE NOT EXISTS
(SELECT *
FROM UNIVERSITY B
WHERE A.RATING > = B.RATING
AND B.CITY = ‘М о сква ’);
может бытьп ред став лен и след ующ емв ид е
SELECT *
FROM UNIVERSITY A
WHERE 1 >
(SELECT COUNT(*)
FROM UNIVERSITY B
WHERE A.RATING > = B.RATING
AND B.CITY = ‘М о сква ’);
|
|
62 |
|
|
УП Р АЖ НЕ НИ Я |
|
|
|
|
37.Н а п ишите з а п рос, |
в ыбира ющ ий |
д анные о наз в аниях |
унив ерситетов , |
|
р ейтинг которых |
ра в ен или |
п рев осход ит |
рейтинг |
Воронежского |
госуд а рств енного унив ер ситета. |
|
|
|
|
38.Н а п ишитез а п рос, |
исп ольз ующ ий ANY или ALL, |
в ып олняющ ий в ыборку |
д анных о студ ента х, у которых в город еих п остоянного местожительств а нет унив ерситета .
39.Н а п ишите з ап рос, в ыбира ющ ий |
из таблицы |
EXAM_MARKS д а нные о |
|
наз в а ниях п ред метов обуч ения, |
д ля которых |
з нач ение п олуч енных |
на |
э кз амене оценок (п оле MARK) п рев ышает любое з нач ение оценки |
д ля |
||
п ред мета , имеющ его ид ентифика тор рав ный 105. |
|
40.Н а п ишитеэ тот жез ап рос с исп ольз ов аниемMAX.
2.15. О перат ор объ единения UNION
О п ера тор UNION исп ольз уетсяд ляобъед иненияв ыход ных д а нных д в ух или болееSQL-з ап росов в ед иноемножеств о строк и столбцов . Н а п ример,
д ля того, |
ч тобы п олуч ить в од ной таблице фа милии и ид ентификаторы |
студ ентов |
и п реп од ав ателей из М оскв ы, можно исп ольз ов а тьслед ующ ий |
з ап рос. |
|
SELECT ‘С туден т______’, SURNAME, STUDENT_ID
FROM STUDENT
WHERE CITY = ‘М о сква ’
UNION
SELECT ‘Пр епо да ва тель’, SURNAME, LECTURER_ID
FROM LECTURER
WHERE CITY = ‘М о сква ’;
О братите в нима ние на |
то, ч то |
симв олом “;” (точ ка |
с |
з ап ятой) |
оканч ив ается только п ослед ний з ап рос. |
О тсутств иеэтого симв ола |
в конце |
||
SELECT-з ап роса оз на ч ает, ч то след ующ ий з а ним з ап рос также, |
как и он |
|||
сам, яв ляетсяч а стьюобщ его з ап роса с UNION. |
|
|
||
Исп ольз ов а ние оп ера тора |
UNION в оз можно только п р и |
объед инении |
|
63 |
|
|
з ап росов , |
соотв етств ующ иестолбцы которых со в м ест и м ы по |
о бъ ед и нени ю. |
|
То есть, |
соотв етств ующ ие ч ислов ые п оля |
д олжны иметь п олностью |
|
сов п а д ающ ие тип и р аз мер, симв ольные |
п оля д олжны |
иметь точ но |
сов п а д ающ ее колич еств о симв олов . Е сли NULL-з нач ения з а п рещ ены д ля столбца хотя бы од ного любого п од з ап роса объед инения, то они д олжны бытьз ап рещ ены и д ляв сех соотв етств ующ их столбцов в д ругих п од з ап р осах объед инения.
2.16. Уст ранение дубл ирования в UNION
В отлич ие от обыч ных з а п росов UNION а в томатич ески исключ ает из в ыход ных д а нных д ублика ты строк, на п ример, в з ап р осе
SELECT CITY
FROM STUDENT
UNION
SELECT CITY
FROM LECTURER;
сов п а д ающ иена именов а ниягор од ов буд ут исключ ены.
Е сли в се же необход имо кажд ом з ап росе в ыв ести в се строки нез а в исимо от того, имеются ли такие же строки в д ругих объед иняемых з ап росах, то след ует исп ольз ов атьв о множеств енном з ап росеконструкциюс оп ераторомUNION ALL. Так в з ап росе
SELECT CITY
FROM STUDENT
UNION ALL
SELECT CITY
FROM LECTURER;
д ублика ты з на ч ений город ов , в ыв од имые в тор ой ч астью з ап роса, небуд ут исключ аться.
Прив ед ем ещ е од ин п р имер исп ольз ов а ния оп ера тора UNION. Пусть необход имо состав итьотч ет, сод ержащ ий д лякажд ой д аты сд ач и экз аменов св ед ения п о ка жд ому студ енту, п олуч ив шему максима льную или минимальнуюоценки.
SELECT ‘ма кс о ц’, A.STUDENT_ID, SURNAME, MARK, EXAM_DATE
64
FROM STUDENT A, EXAM_MARKS B WHERE (A.STUDENT_ID = B.STUDENT_ID
AND B.MARK =
(SELECT MAX(MARK)
FROM EXAM_MARKS C
WHERE C.EXAM_DATE = B.EXAM_DATE))
UNION ALL
SELECT ‘ми н о ц ’, A.STUDENT_ID, SURNAME, MARK, EXAM_DATE FROM STUDENT A, EXAM_MARKS B
WHERE (A.STUDENT_ID = B.STUDENT_ID AND B.MARK =
(SELECT MIN(MARK)
FROM EXAM_MARKS C
WHERE C.EXAM_DATE = B.EXAM_DATE));
Д ляотлич иястрок, в ыв од имых п ерв ой и в торой ч астями з а п роса, в них
в ста в лены текстов ыеконста нты ‘ма кс о ц’и ‘ми н |
о ц ’. |
|
|
В п рив ед енном з а п росе агрегирующ ие |
функции |
исп ольз уются в |
|
п од з ап росах. Э то |
яв ляется нерациона льным |
с точ ки |
з рения в ремени, |
з атр ач ив аемого на |
в ып олнениез а п роса (см. раз д ел 2.9). |
Б олееэффектив на |
форма з ап роса, в оз в ращ ающ его а налогич ный рез ультат:
SELECT ‘ма кс о ц’, A.STUDENT_ID, SURNAME, E.MARK, E.EXAM_DATE FROM STUDENT A,
(SELECT B.STUDENT_ID, B.MARK, B.EXAM_DATE FROM EXAM_MARKS B,
(SELECT MAX(MARK) AS MAX_MARK, C.EXAM_DATE FROM EXAM_MARKS C
GROUP BY C.EXAM_DATE) D
WHERE B.EXAM_DATE=D.EXAM_DATE AND B.MARK=MAX_MARK) E
WHERE A.STUDENT_ID=E.STUDENT_ID
UNION ALL
SELECT ‘ми н о ц ’, A.STUDENT_ID, SURNAME, E.MARK, E.EXAM_DATE FROM STUDENT A,
(SELECT B.STUDENT_ID, B.MARK, B.EXAM_DATE FROM EXAM_MARKS B,
(SELECT MIN(MARK) AS MIN_MARK, C.EXAM_DATE FROM EXAM_MARKS C
GROUP BY C.EXAM_DATE) D
65
WHERE B.EXAM_DATE=D.EXAM_DATE
AND B.MARK=MIN_MARK) E
WHERE A.STUDENT_ID=E.STUDENT_ID
2.17. И спол ь з ование UNION сORDER BY
Пред ложение ORDER BY |
п рименяется д ля уп оряд оч ения в ыход ных |
|
д анных объед инения з а п росов |
та к же, |
как и д ля отд ельных з ап росов . |
Послед ний п ример, п р и необход имости |
уп оряд оч ения в ыход ных д анных |
з ап роса п о фамилиямстуд ентов и д ата мэкз аменов , может в ыгляд етьтак:
SELECT ‘ма кс о ц’, A.STUDENT_ID, SURNAME, E.MARK, E.EXAM_DATE FROM STUDENT A,
(SELECT B.STUDENT_ID, B.MARK, B.EXAM_DATE FROM EXAM_MARKS B,
(SELECT MAX(MARK) AS MAX_MARK, C.EXAM_DATE FROM EXAM_MARKS C
GROUP BY C.EXAM_DATE) D WHERE B.EXAM_DATE=D.EXAM_DATE AND B.MARK=MAX_MARK) E
WHERE A.STUDENT_ID=E.STUDENT_ID
UNION ALL
SELECT ‘ми н о ц ’, A.STUDENT_ID, SURNAME, E.MARK, E.EXAM_DATE FROM STUDENT A,
(SELECT B.STUDENT_ID, B.MARK, B.EXAM_DATE FROM EXAM_MARKS B,
(SELECT MIN(MARK) AS MIN_MARK, C.EXAM_DATE FROM EXAM_MARKS C
GROUP BY C.EXAM_DATE) D
WHERE B.EXAM_DATE=D.EXAM_DATE AND B.MARK=MIN_MARK) E
WHERE A.STUDENT_ID=E.STUDENT_ID ORDER BY SURNAME, E.EXAM_DATE;
66
2.18. В неш нее объ единение
Ч асто п олез на оп ерация объед инения д в ух з ап росов , в которой в торой
з ап рос в ыбира ет строки, |
исключ енныеп ер в ым. Та кая оп ерация наз ыв ается |
|||||||||
в нешнимобъед инением. |
|
|
|
|
|
|
|
|||
Рассмотрим п ример. |
Пусть в |
таблице STUDENT имеются з ап иси о |
||||||||
студ ентах, |
в которых |
не указ ан |
ид ентификатор унив ерситета. |
Требуется |
||||||
соста в итьсп исок студ ентов |
с указ анием на именов а нияунив ерситета д лятех |
|||||||||
студ ентов , |
у которых |
эти |
д анные есть, |
но |
п ри э том не отбра сыв ая и |
|||||
студ ентов , |
у которых унив ерситет не ука з ан. М ожно |
п олуч итьжелаемые |
||||||||
св ед ения, |
сфор миров а в |
|
объед инение д в ух |
з а п росов , |
од ин из |
которых |
||||
в ып олняет в ыборку |
студ ентов с наз в а ниями |
их унив ерситетов , |
а в торой |
|||||||
в ыбирает студ ентов |
с NULL-з нач ениями |
п олеUNIV_ID. В д а нном случ ае |
||||||||
оказ ыв ается п олез ной |
в оз можность в став ки |
в з ап рос |
констант, |
в на шем |
||||||
случ а е текстов ой конста нты ‘н е и звестен ’, |
ч тобы отметитьв сп иске тех |
|||||||||
студ ентов , у которых отсутств ует информацияоб унив ерситете. |
|
SELECT SURNAME, NAME, UNIV_NAME
FROM STUDENT, UNIVERSITY
WHERE STUDENT.UNIV_ID = UNIVERSITY.UNIV_ID
UNION
SELECT SURNAME, NAME, ‘н еи звестен ’
FROM STUDENT
WHERE UNIV_ID IS NULL
ORDER BY 1;
Д ля сов местимости столбцов объед иняемых з ап росов конста нту ‘н еи звестен ’ в о в торомз ап росеслед ует д оп олнитьп робела ми та к, ч тобы ее д лина соотв етств ов а ла д лине п оля UNIV_NAME или исп ольз ов ать д ля согла сов аниятип ов функцию CAST. В некоторых СУ Б Д согласов а ниетип ов п оляи з амещ ающ ей его текстов ой конста нты осущ еств ляетсяав томатич ески.
УП Р АЖ НЕ НИ Я
41.Соз д айте объед инение д в ух з ап росов , которые в ыд ают з нач ения п олей UNIV_NAME, CITY, RATING д ляв сех унив ерситетов . Теиз них, у которых р ейтинг рав ен или в ыше300, д олжны иметькомментарий ‘Вы со ки й’, в се остальные– ‘Н и зки й’.
67 42.Н а п ишите кома нд у, которая в ыд ает сп исок фа милий студ ентов , с
комментарием ‘успева ет’ у студ ентов , |
имеющ их в се п оложительные |
оценки, комментарием ‘н е успева ет’ |
д ля сд а в ав ших экз амены, но |
имеющ их хотя бы од ну неуд ов летв орительную оценку, и комментарием ‘н е сда ва л’ – д ля в сех остальных. В в ыв од имом рез ультате фамилии студ ентов уп оряд оч итьп о а лфа в иту.
43.Выв ед итеобъед иненный сп исок студ ентов и п реп од ав ателей, жив ущ их в
М оскв е, |
с |
соотв етств ующ ими |
комментариями |
‘студен т’ или |
‘пр епо да ва тель’. |
|
|
||
44.Выв ед ите |
объед иненный сп исок |
студ ентов |
и п реп од ав ателей |
|
Воронежского |
госуд арств енного унив ерситета с |
соотв етств ующ ими |
||
комментариями ‘студен т’ или ‘пр епо да ва тель’. |
|
2.19.С оединение т абл иц сиспол ь зованием операт ора JOIN
Е сли в оп ератореSELECT п ослеключ ев ого слов а FROM указ ыв аетсяне од на, а д в е таблицы, то в рез ультате в ып олнения з ап р оса, в котором
отсутств ует |
п ред ложение WHERE, кажд а я стр ока од ной таблицы буд ет |
соед инена с |
кажд ой стр окой в торой та блицы. Та кая оп ерация наз ыв ается |
д ека р т о в ым |
пр о и зв ед ени ем или по лны м (CROSS) со ед и нени ем таблиц баз ы |
д анных. Сама п о себеэ та оп ерациянеимеет п рактич еского з нач ения, более того, п ри ошибоч ном исп ольз ов ании она может п рив ести к неожид анным
нештатным ситуа циям, так как в этом случ аев отв етена з ап рос колич еств о |
|
з ап исей буд ет ра в но п роиз в ед ению ч исла з а п исей |
соед иняемых таблица х, |
то есть может оказ аться ч рез в ыч а йно большим. |
Соед инениетаблиц имеет |
смысл тогд а, когд а соед иняютсяне все строки |
исход ных та блиц, а только те, |
||
которые интересуют |
п ольз ов ателя. Такое |
огранич ение может быть |
|
осущ еств лено с п омощ ью исп ольз ов а ния в |
з ап росе |
соотв етств ующ его |
|
услов ия в п ред ложении |
WHERE. Таким обр аз |
ом, SQL п |
оз в оляет в ыв од ить |
информациюиз нескольких таблиц, св яз ыв аяих п о з нач ениямоп ред еленных п олей.
Н а п ример, если необход имо п олуч ить фамилии студ ентов |
(та блица |
STUDENT) и д ля кажд ого студ ента – наз в ания унив ерситетов |
(та блица |
68
UNIVERSITY), расп оложенных в город е, гд ежив ет студ ент, то необход имо п олуч ить в се комбина ции з ап исей о студ ентах и унив ерситетах в обеих таблица х, в которых з на ч ение п оля CITY сов п ад ает. Э то можно сд елатьс
помощ ьюслед ующ его з ап роса .
SELECT STUDENT.SURNAME, UNIVERSITY.UNIV_NAME, STUDENT.CITY FROM STUDENT, UNIVERSITY
WHERE STUDENT.CITY = UNIVERSITY.CITY;
Соед инение, исп ольз ующ ее п ред икаты, |
основ а нные на |
рав енств а х, |
наз ыв а ется экви со ед и нени ем . Рассмотренный |
п ример соед инения таблиц |
|
относятся к в ид у так наз ыв аемого внут р еннего (INNER) со ед и нени я. При |
||
таком тип есоед инения соед иняются только тестроки та блиц, |
д ля которых |
яв ляется истинным п р ед икат, з ад ав аемый в п ред ложении ON в ып олняемого з ап роса.
Прив ед енный в ышез ап рос может бытьз а п исан инач е, с исп ольз ов а нием ключ ев ого слов а JOIN.
SELECT STUDENT.SURNAME, UNIVERSITY.UNIV_NAME, STUDENT.CITY
FROM STUDENT INNER JOIN UNIVERSITY
ON STUDENT.CITY = UNIVERSITY.CITY;
К люч ев ое слов о INNER в з ап р осе может бытьоп ущ ено, |
та к как эта |
|||||
оп цияв оп ератореJOIN д ейств ует п о умолч анию. |
|
|
|
|||
Рассмотренный |
в ыше |
случ а й |
п олного |
соед инения |
(д екартов а |
|
п роиз в ед ения та блиц) |
с исп ольз ов анием ключ ев ого слов а |
JOIN |
буд ет |
|||
в ыгляд етьслед ующ имобраз ом |
|
|
|
|
||
SELECT * FROM STUDENT JOIN UNIVERSITY; |
|
|
||||
ч то экв ив а лентно |
|
|
|
|
|
|
SELECT * FROM STUDENT, UNIVERSITY; |
|
|
|
|||
Заметим, ч то в |
СУ Б Д |
Oracle |
з а д ав аемый |
станд артом |
яз ыка |
SQL |
оп ератор JOIN неп од д ержив ается.
69
2.19.1.О перац ии соединения т абл иц посредст вом ссы л очной ц ел ост ност и
Информация в таблица х STUDENT и |
EXAM_MARKS уже св яз ана |
|
п осред ств ом п оля STUDENT_ID. В таблице |
STUDENT п оле STUDENT_ID |
|
яв ляется п ер в ич ным ключ ом, а в таблице EXAM_MARKS, |
ссыла ющ имся на |
|
него в нешним ключ ом. Состояние св яз анных таким |
обра з ом таблиц |
наз ыв а етсясостоянием ссылоч ной целостности. В д анном случ а ессылоч ная
целостность этих таблиц |
п од р аз умев ает, ч то |
ка ж д о м у з нач ению п оля |
STUDENT_ID в таблицеEXAM_MARKS о бяза т ельно соотв етств ует т а ко е ж е |
||
зна чени е п оля STUDENT_ID в таблице STUDENT. Д ругими слов а ми, в |
||
таблице EXAM_MARKS не может бытьз а п исей, |
имеющ их ид ентификаторы |
|
студ ентов , которых нет |
та блице STUDENT. |
Станд артное п рименение |
оп ерации соед инениясостоит в из в леч ении д анных в терминах этой св яз и.
Ч тобы п олуч ить сп исок фамилий |
студ ентов с п олуч енными ими |
оценка ми и ид ентификатор ами п ред метов |
можно исп ольз ов атьслед ующ ий |
з ап рос: |
|
SELECT SURNAME, MARK, SUBJ_ID
FROM STUDENT, EXAM_MARKS
WHERE STUDENT.STUDENT_ID = EXAM_MARKS.STUDENT_ID;
Тот же самый рез ультат может быть п олуч ен п ри исп ольз ов ании в з ап росе д ля з ад а ния оп ерации соед инения таблиц ключ ев ого слов а JOIN. Зап рос с оп ера торомJOIN в ыгляд ит след ующ имобраз ом
SELECT SURNAME, MARK
FROM STUDENT JOIN EXAM_MARKS
ON STUDENT.STUDENT_ID = EXAM_MARKS.STUDENT_ID;
Х отя в ышереч ьшла о соед инении д в ух таблиц, можно сформиров ать
з ап росы п утемсоед иненияболееч емд в ух таблиц. |
|
Пусть требуется на йти фамилии в сех студ ентов , |
п олуч ив ших |
неуд ов летв ор ительнуюоценку, в местес наз в а ниями п р ед метов |
обуч ения, п о |
которымп олуч ена э та оценка . |
|
SELECT SUBJ_NAME, SURNAME, MARK
FROM STUDENT, SUBJECT, EXAM_MARKS
WHERE STUDENT.STUDENT_ID = EXAM_MARKS.STUDENT_ID AND SUBJECT.SUBJ_ID = EXAM_MARKS.SUBJ_ID
70
AND EXAM_MARKS.MARK = 2;
То жесамоес исп ольз ов а ниемоп ератор а JOIN
SELECT SUBJ_NAME, SURNAME, MARK
FROM STUDENT JOIN SUBJECT JOIN EXAM_MARKS ON STUDENT.STUDENT_ID = EXAM_MARKS.STUDENT_ID
AND SUBJECT.SUBJ_ID = EXAM_MARKS.SUBJ_ID AND EXAM_MARKS.MARK = 2;
2.19.2. |
В неш нее соединение т абл иц |
К ак |
отмеч а лось ранее, п ри исп ольз ов а нии внут р еннего (INNER) |
соед инениятаблиц соед иняютсятолько теих строки, в которых сов п ад ают |
|
з нач ения п олей, з ад ав аемые в п р ед ложении WHERE з ап роса. О д нако в о |
многих случ аях это может п рив ести к нежела тельной п отереинформа ции.
Рассмотрим ещ ераз |
п рив ед енный в ышеп ример з а п роса на в ыборку сп иска |
|
фамилий студ ентов |
с п олуч енными ими оценка ми и |
ид ентифика торами |
п ред метов . Пр и исп ольз ов ании, ка к это было сд ела но в |
р ассматрив аемом |
п римере, в нутреннего соед иненияв рез ультат з а п роса неп оп ад ут студ енты, которыеещ енесд а в али экз амены и которые, след ов ательно, отсутств уют таблицеEXAM_MARKS. Е сли женеобход имо иметьз ап иси об этих студ ентах в в ыд ав аемом з ап росом сп иске, то можно п рисоед инить св ед ения о студ ентах, несд а в а в ших экз амен, п утем исп ольз ов а нияоп ератора UNION с соотв етств ующ имз ап росом. Н а п ример, след ующ имобра з ом:
SELECT SURNAME, CAST MARK AS CHAR(1), CAST SUBJ_ID AS CHAR(10) FROM STUDENT, EXAM_MARKS
WHERE STUDENT.STUDENT_ID = EXAM_MARKS.STUDENT_ID
UNION
SELECT SURNAME, CAST NULL AS CHAR(1), CAST NULL AS CHAR(10)
FROM STUDENT
WHERE NOT EXIST (SELECT *
FROM EXAM_MARKS
WHERE STUDENT.STUDENT_ID = EXAM_MARKS.STUDENT_ID);
(з д есьфункция п реобразов ания тип ов CAST исп ольз уется д ля обесп еч ения сов местимости тип ов п олей объед иняемых з а п росов ).