Усл<strong>о</strong>вный <strong>о</strong>перат<strong>о</strong>р групп<strong>о</strong>выхфункц<strong>и</strong>й HAVINGМы раз<strong>о</strong>брал<strong>и</strong>, как <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>вать групп<strong>о</strong>выефункц<strong>и</strong><strong>и</strong>, н<strong>о</strong> п<strong>о</strong>ка не рассм<strong>о</strong>трел<strong>и</strong> случа<strong>и</strong>, к<strong>о</strong>гдабывает не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong> пр<strong>и</strong>менять <strong>о</strong>пределенныеусл<strong>о</strong>в<strong>и</strong>я к групп<strong>о</strong>в<strong>о</strong>й функц<strong>и</strong><strong>и</strong>. Напр<strong>и</strong>мер, не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong>узнать среднеар<strong>и</strong>фмет<strong>и</strong>ческую зарплатус<strong>о</strong>трудн<strong>и</strong>к<strong>о</strong>в, разб<strong>и</strong>тую п<strong>о</strong> зан<strong>и</strong>маемымд<strong>о</strong>лжн<strong>о</strong>стям, с усл<strong>о</strong>в<strong>и</strong>ем, чт<strong>о</strong>бы эт<strong>о</strong>т п<strong>о</strong>казательдля группы не превышал 2000. Уч<strong>и</strong>тывая пр<strong>о</strong>йденныйматер<strong>и</strong>ал, м<strong>о</strong>жет в<strong>о</strong>зн<strong>и</strong>кнуть уверенн<strong>о</strong>сть,чт<strong>о</strong> запр<strong>о</strong>с д<strong>о</strong>лжен выглядеть следующ<strong>и</strong>м<strong>о</strong>браз<strong>о</strong>м:SELECT job, AVG (sal)FROM empWHERE AVG(sal) < 2000GROUP BY jobН<strong>о</strong> в<strong>о</strong> время вып<strong>о</strong>лнен<strong>и</strong>я данн<strong>о</strong>г<strong>о</strong> запр<strong>о</strong>са с<strong>и</strong>стемавыдаст вам <strong>о</strong>ш<strong>и</strong>бку ORA-00934: groupfunction is not allowed here, к<strong>о</strong>т<strong>о</strong>рая указываетна т<strong>о</strong>, чт<strong>о</strong> нед<strong>о</strong>пуст<strong>и</strong>м<strong>о</strong> <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>вать групп<strong>о</strong>вуюфункц<strong>и</strong>ю в <strong>о</strong>пц<strong>и</strong><strong>и</strong> WHERE. Эт<strong>о</strong> пр<strong>о</strong><strong>и</strong>сх<strong>о</strong>д<strong>и</strong>т п<strong>о</strong>следующей пр<strong>и</strong>ч<strong>и</strong>не: перед тем как п<strong>о</strong>став<strong>и</strong>тьусл<strong>о</strong>в<strong>и</strong>е на группу, не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong> чт<strong>о</strong>бы <strong>о</strong>на быласперва п<strong>о</strong>дсч<strong>и</strong>тана, а усл<strong>о</strong>в<strong>и</strong>я, расп<strong>о</strong>лагающ<strong>и</strong>есяв WHERE, пр<strong>и</strong>меняются пр<strong>и</strong> кажд<strong>о</strong>м выб<strong>о</strong>рестр<strong>о</strong>к<strong>и</strong>. Вследств<strong>и</strong>е эт<strong>о</strong>г<strong>о</strong> не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>ма д<strong>о</strong>п<strong>о</strong>лн<strong>и</strong>тельнаясекц<strong>и</strong>я, к<strong>о</strong>т<strong>о</strong>рая будет п<strong>о</strong>зв<strong>о</strong>лятьвставлять усл<strong>о</strong>в<strong>и</strong>е на ур<strong>о</strong>вне группы, для чег<strong>о</strong> <strong>и</strong>служ<strong>и</strong>т <strong>о</strong>перат<strong>о</strong>р HAVING.Итак, вы не м<strong>о</strong>жете <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>вать <strong>о</strong>пц<strong>и</strong>ю WHEREдля групп<strong>о</strong>вых функц<strong>и</strong>й, а для выставлен<strong>и</strong>я62 7/12усл<strong>о</strong>в<strong>и</strong>й для групп<strong>о</strong>вых функц<strong>и</strong>й не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong><strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>вать <strong>о</strong>пц<strong>и</strong>ю HAVING. Стр<strong>о</strong>к<strong>и</strong>, с<strong>о</strong><strong>о</strong>тветствующ<strong>и</strong>еусл<strong>о</strong>в<strong>и</strong>ям HAVING, будут <strong>о</strong>т<strong>о</strong>браженыв <strong>и</strong>т<strong>о</strong>г<strong>о</strong>в<strong>о</strong>й выб<strong>о</strong>рке п<strong>о</strong> табл<strong>и</strong>це. Так<strong>и</strong>м <strong>о</strong>браз<strong>о</strong>м,<strong>о</strong>бщая схема запр<strong>о</strong>са пр<strong>и</strong>мет следующ<strong>и</strong>й в<strong>и</strong>д:SELECT * | {[DISTINCT] column | expression [[as]allias], ...}FROM table_nameWHERE condition(s)[HAVING group_condition][GROUP BY column][ORDER BY {column | expression} [asc | desc ]]Пр<strong>и</strong>мер, пр<strong>и</strong>веденный выше, будет решен с п<strong>о</strong>м<strong>о</strong>щьюследующег<strong>о</strong> запр<strong>о</strong>са:SELECT job, MIN (sal)FROM empHAVING AVG(sal) < 2000GROUP BY jobВл<strong>о</strong>женныегрупп<strong>о</strong>вые функц<strong>и</strong><strong>и</strong>Вл<strong>о</strong>женная групп<strong>о</strong>вая функц<strong>и</strong>я сч<strong>и</strong>тается так<strong>о</strong>в<strong>о</strong>йв случае, есл<strong>и</strong> <strong>о</strong>на является параметр<strong>о</strong>мдля друг<strong>о</strong>й групп<strong>о</strong>в<strong>о</strong>й функц<strong>и</strong><strong>и</strong>. Рассм<strong>о</strong>тр<strong>и</strong>мпр<strong>и</strong>мер, к<strong>о</strong>гда вам не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong> выясн<strong>и</strong>ть макс<strong>и</strong>мальн<strong>о</strong>б<strong>о</strong>льшую среднеар<strong>и</strong>фмет<strong>и</strong>ческуюзарплату с<strong>о</strong>трудн<strong>и</strong>к<strong>о</strong>в разных спец<strong>и</strong>альн<strong>о</strong>стей.На первый взгляд м<strong>о</strong>жет п<strong>о</strong>казаться, чт<strong>о</strong> нап<strong>и</strong>сатьп<strong>о</strong>д<strong>о</strong>бный запр<strong>о</strong>с сл<strong>о</strong>жн<strong>о</strong>, <strong>о</strong>днак<strong>о</strong> с <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>ван<strong>и</strong>емвл<strong>о</strong>женн<strong>о</strong>й групп<strong>о</strong>в<strong>о</strong>й функц<strong>и</strong><strong>и</strong>все знач<strong>и</strong>тельн<strong>о</strong> упр<strong>о</strong>щается. Запр<strong>о</strong>с пр<strong>и</strong>метследующ<strong>и</strong>й в<strong>и</strong>д:SELECT MAX(AVG(sal))FROM empGROUP BY salЧ<strong>и</strong>сл<strong>о</strong>вые функц<strong>и</strong><strong>и</strong><strong>и</strong> функц<strong>и</strong><strong>и</strong> <strong>о</strong>браб<strong>о</strong>тк<strong>и</strong> датыЧ<strong>и</strong>сл<strong>о</strong>вые функц<strong>и</strong><strong>и</strong>В SQL пр<strong>и</strong>меняются 3 тр<strong>и</strong> <strong>о</strong>сн<strong>о</strong>вные ч<strong>и</strong>сл<strong>о</strong>выефункц<strong>и</strong><strong>и</strong>: ROUND, TRUNC <strong>и</strong> MOD.Функц<strong>и</strong>я ROUND (column | expression, n) в<strong>о</strong>звращаетч<strong>и</strong>сленн<strong>о</strong>е выражен<strong>и</strong>е, <strong>о</strong>кругленн<strong>о</strong>ед<strong>о</strong> указанн<strong>о</strong>й дл<strong>и</strong>ны <strong>и</strong>л<strong>и</strong> с заданн<strong>о</strong>й т<strong>о</strong>чн<strong>о</strong>стью.Т<strong>о</strong>чн<strong>о</strong>сть, с к<strong>о</strong>т<strong>о</strong>р<strong>о</strong>й д<strong>о</strong>лжн<strong>о</strong> <strong>о</strong>кругляться выражен<strong>и</strong>е,указывается в функц<strong>и</strong><strong>и</strong>. Есл<strong>и</strong> вт<strong>о</strong>р<strong>о</strong>йаргумент представлен п<strong>о</strong>л<strong>о</strong>ж<strong>и</strong>тельным значен<strong>и</strong>ем,т<strong>о</strong> выражен<strong>и</strong>е NUMERIC_EXPRESSION<strong>о</strong>кругляется д<strong>о</strong> к<strong>о</strong>л<strong>и</strong>чества ц<strong>и</strong>фр п<strong>о</strong>сле запят<strong>о</strong>й.Есл<strong>и</strong> же вт<strong>о</strong>р<strong>о</strong>й аргумент представлен <strong>о</strong>тр<strong>и</strong>цательнымч<strong>и</strong>сл<strong>о</strong>м, т<strong>о</strong> <strong>о</strong>кругляется та часть выражен<strong>и</strong>я,к<strong>о</strong>т<strong>о</strong>рая расп<strong>о</strong>л<strong>о</strong>жена слева <strong>о</strong>т запят<strong>о</strong>й.SELECT ROUND (54533.45672124,3)FROM dualROUND (54533.45672124,3)54 533,46SELECT ROUND (54533.45672124,-2)FROM dualROUND (54533.45672124,-2)54 500,00Функц<strong>и</strong>я TRUNC (column | expression, n) в<strong>о</strong>звращаетцелую часть ч<strong>и</strong>сла с плавающей запят<strong>о</strong>й. Вкачестве вт<strong>о</strong>р<strong>о</strong>г<strong>о</strong> аргумента п<strong>о</strong>дразумевается,д<strong>о</strong> как<strong>о</strong>г<strong>о</strong> значен<strong>и</strong>я д<strong>о</strong> запят<strong>о</strong>й будет пр<strong>о</strong><strong>и</strong>зведен<strong>о</strong><strong>о</strong>круглен<strong>и</strong>е.SELECT TRUNC (54533.45672124,3)FROM dualTRUNC (54533.45672124,3)54 533,456Функц<strong>и</strong>я MOD (m, n) выдает <strong>о</strong>стат<strong>о</strong>к <strong>о</strong>т делен<strong>и</strong>я.Есл<strong>и</strong> результат делен<strong>и</strong>я представляется вв<strong>и</strong>де цел<strong>о</strong>г<strong>о</strong> ч<strong>и</strong>сла, т<strong>о</strong> результат <strong>и</strong>гн<strong>о</strong>р<strong>и</strong>руется. Вкачестве перв<strong>о</strong>г<strong>о</strong> аргумента берется дел<strong>и</strong>м<strong>о</strong>е, ав качестве вт<strong>о</strong>р<strong>о</strong>г<strong>о</strong> - дел<strong>и</strong>тель.SELECT MOD (100,30)FROM dualMOD (100,30)10
Функц<strong>и</strong><strong>и</strong> <strong>о</strong>браб<strong>о</strong>тк<strong>и</strong> датыД<strong>о</strong> с<strong>и</strong>х п<strong>о</strong>р мы <strong>о</strong>бращал<strong>и</strong>сь т<strong>о</strong>льк<strong>о</strong> с ч<strong>и</strong>слам<strong>и</strong> <strong>и</strong>стр<strong>о</strong>кам<strong>и</strong>. Теперь пр<strong>и</strong>шл<strong>о</strong> время <strong>о</strong>браб<strong>о</strong>тать <strong>и</strong>нф<strong>о</strong>рмац<strong>и</strong>ют<strong>и</strong>па даты. К<strong>о</strong>нечн<strong>о</strong>, есл<strong>и</strong> уч<strong>и</strong>тыватьт<strong>о</strong>т факт, чт<strong>о</strong> мн<strong>о</strong>г<strong>и</strong>е <strong>о</strong>тчеты не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong> п<strong>о</strong>лучатьза <strong>о</strong>пределенный пер<strong>и</strong><strong>о</strong>д времен<strong>и</strong>, т<strong>о</strong> част<strong>о</strong>та <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>ван<strong>и</strong>яфункц<strong>и</strong>й, <strong>о</strong>брабатывающ<strong>и</strong>х дату,резк<strong>о</strong> в<strong>о</strong>зрастает. Пр<strong>и</strong> раб<strong>о</strong>те с дат<strong>о</strong>й част<strong>о</strong> бываетне<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong> <strong>о</strong>бращаться к текущей дате. Для эт<strong>о</strong>г<strong>о</strong>в SQL <strong>и</strong>сп<strong>о</strong>льзуется функц<strong>и</strong>я SYSDATE, к<strong>о</strong>т<strong>о</strong>рая в<strong>о</strong>звращаетзначен<strong>и</strong>е текущей даты <strong>и</strong> времен<strong>и</strong> <strong>и</strong>збазы данных. Так<strong>и</strong>м <strong>о</strong>браз<strong>о</strong>м, текущая дата, взятаяпр<strong>и</strong> п<strong>о</strong>м<strong>о</strong>щ<strong>и</strong> SYSDATE, м<strong>о</strong>жет <strong>о</strong>тл<strong>и</strong>чаться <strong>о</strong>т с<strong>и</strong>стемн<strong>о</strong>г<strong>о</strong>времен<strong>и</strong> на вашем к<strong>о</strong>мпьютере. Чт<strong>о</strong>бы<strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>вать эту функц<strong>и</strong>ю, д<strong>о</strong>стат<strong>о</strong>чн<strong>о</strong> указать еев разделе select. Она <strong>и</strong>звлечет результат, несм<strong>о</strong>тряна т<strong>о</strong>, какая табл<strong>и</strong>ца участвует в разделе FROM.В качестве пр<strong>и</strong>мера п<strong>о</strong>пр<strong>о</strong>буем узнать текущуюдату <strong>и</strong>з нашей базы данных:SELECT SYSDATEFROM dualSYSDATE10.09.2010 03:13:51Функц<strong>и</strong>я MONTHS_BETWEEN (date1, date2)<strong>и</strong>сп<strong>о</strong>льзуется для выяснен<strong>и</strong>я разн<strong>и</strong>цы времен<strong>и</strong>между двумя датам<strong>и</strong>. Она <strong>о</strong>пределяет, на ск<strong>о</strong>льк<strong>о</strong>месяцев date1 б<strong>о</strong>льше date2. В случае, есл<strong>и</strong>date1 меньше date2, т<strong>о</strong> результат будет <strong>о</strong>тр<strong>и</strong>цательным.Результат будет представлен в в<strong>и</strong>дерац<strong>и</strong><strong>о</strong>нальн<strong>о</strong>г<strong>о</strong> ч<strong>и</strong>сла, в к<strong>о</strong>т<strong>о</strong>р<strong>о</strong>м цел<strong>о</strong>е ч<strong>и</strong>сл<strong>о</strong>будет <strong>о</strong>значать к<strong>о</strong>л<strong>и</strong>честв<strong>о</strong> месяцев, а др<strong>о</strong>бнаячасть к<strong>о</strong>л<strong>и</strong>честв<strong>о</strong> дней, с<strong>о</strong>гласн<strong>о</strong> запр<strong>о</strong>шенн<strong>о</strong>мумесяцу.SELECT MONTHS_BETWEEN('25-DEC-10', '25-DEC-09') result1,MONTHS_BETWEEN('12-OCT-10', '25-DEC-09') result2,MONTHS_BETWEEN('12-AUG-08', '02-NOV-09') result3FROM dualRESULT1 12,00RESULT2 9,58RESULT3 9,58Функц<strong>и</strong>я ADD_MONTHS (date, n) пр<strong>и</strong>бавляетк<strong>о</strong>л<strong>и</strong>честв<strong>о</strong> (n) месяцев к указанн<strong>о</strong>й дате.В качестве n <strong>и</strong>сп<strong>о</strong>льзуется т<strong>о</strong>льк<strong>о</strong> цел<strong>о</strong>е ч<strong>и</strong>сл<strong>о</strong>,<strong>о</strong>днак<strong>о</strong> <strong>и</strong> <strong>о</strong>н<strong>о</strong> м<strong>о</strong>жет быть <strong>о</strong>тр<strong>и</strong>цательным,чт<strong>о</strong> п<strong>о</strong>зв<strong>о</strong>л<strong>и</strong>т <strong>о</strong>тн<strong>и</strong>мать месяцы <strong>о</strong>т <strong>и</strong>сх<strong>о</strong>дн<strong>о</strong>йдаты.Функц<strong>и</strong>я NEXT_DAY (date, 'char') п<strong>о</strong>м<strong>о</strong>гает выч<strong>и</strong>сл<strong>и</strong>тьследующ<strong>и</strong>й день недел<strong>и</strong>. Так, напр<strong>и</strong>мер,мы м<strong>о</strong>жем узнать, к<strong>о</strong>гда будет следующ<strong>и</strong>йп<strong>о</strong>недельн<strong>и</strong>к. Естественн<strong>о</strong>, вмест<strong>о</strong> char не<strong>о</strong>бх<strong>о</strong>д<strong>и</strong>м<strong>о</strong>указывать день недел<strong>и</strong> на англ<strong>и</strong>йск<strong>о</strong>мязыке, н<strong>о</strong> char также м<strong>о</strong>жет пр<strong>и</strong>н<strong>и</strong>мать <strong>и</strong> ч<strong>и</strong>сл<strong>о</strong>в<strong>о</strong>езначен<strong>и</strong>е.Функц<strong>и</strong>я LAST_DAY (date) указывает п<strong>о</strong>следн<strong>и</strong>йдень месяца аргумента.Ар<strong>и</strong>фмет<strong>и</strong>ческ<strong>и</strong>е <strong>о</strong>перац<strong>и</strong><strong>и</strong>с дат<strong>о</strong>йПр<strong>и</strong> раб<strong>о</strong>те с дат<strong>о</strong>й также м<strong>о</strong>жн<strong>о</strong> <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>ватьтак<strong>и</strong>е ар<strong>и</strong>фмет<strong>и</strong>ческ<strong>и</strong>е действ<strong>и</strong>я, как сл<strong>о</strong>жен<strong>и</strong>е<strong>и</strong> выч<strong>и</strong>тан<strong>и</strong>е:Так выглядят пр<strong>и</strong>меры <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>ван<strong>и</strong>я <strong>о</strong>перац<strong>и</strong>йDATE (+ <strong>и</strong>л<strong>и</strong> -) NUMBER <strong>и</strong> DATE (+ <strong>и</strong>л<strong>и</strong> -)NUMBER/24:SELECT SYSDATE + 5FROM dualSYSDATE+5 10.14.2010 04:13:02,00SELECT SYSDATE - 5FROM dualОперац<strong>и</strong>яDATE (+ <strong>и</strong>л<strong>и</strong> -) NUMBERDATE - DATEDATE (+ <strong>и</strong>л<strong>и</strong> -) NUMBER/24SYSDATE-5 10.04.2010 04:13:02SELECT SYSDATE + 48/24FROM dualТ<strong>и</strong>пп<strong>о</strong>лученн<strong>о</strong>г<strong>о</strong>результатаDATENUMBERDATESYSDATE+48/24 10.11.2010 04:13:02Итак, сег<strong>о</strong>дня мы рассм<strong>о</strong>трел<strong>и</strong> ч<strong>и</strong>сл<strong>о</strong>вые функц<strong>и</strong><strong>и</strong><strong>и</strong> функц<strong>и</strong><strong>и</strong> <strong>о</strong>браб<strong>о</strong>тк<strong>и</strong> даты, а также науч<strong>и</strong>л<strong>и</strong>сь:• <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>вать групп<strong>о</strong>вые функц<strong>и</strong><strong>и</strong> COUNT,MAX, MIN, SUM <strong>и</strong> AVG;• п<strong>и</strong>сать запр<strong>о</strong>сы, <strong>и</strong>сп<strong>о</strong>льзуя <strong>о</strong>пц<strong>и</strong>ю GROUP BY;• п<strong>и</strong>сать запр<strong>о</strong>сы, <strong>и</strong>сп<strong>о</strong>льзуя <strong>о</strong>пц<strong>и</strong>ю HAVING;• <strong>и</strong>сп<strong>о</strong>льз<strong>о</strong>вать вл<strong>о</strong>женные групп<strong>о</strong>выефункц<strong>и</strong><strong>и</strong>.В <strong>и</strong>т<strong>о</strong>ге <strong>о</strong>бщая схема запр<strong>о</strong>са пр<strong>и</strong><strong>о</strong>брела следующ<strong>и</strong>йв<strong>и</strong>д:SELECT * | {[DISTINCT] column | expression [[as]allias], ...}FROM table_nameWHERE condition(s)[HAVING group_condition][GROUP BY column][ORDER BY {column | expression} [asc | desc ]]Сам<strong>и</strong>р Самед<strong>о</strong>в,эксперт <strong>и</strong>нтернетресурсаSQL.az7/1263