Справочник от Автор24
Поделись лекцией за скидку на Автор24

Функции в SQL

  • 👀 457 просмотров
  • 📌 432 загрузки
Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Конспект лекции по дисциплине «Функции в SQL» pdf
ЛЕКЦИЯ № 6 3.2.3. Функции в SQL................................................... 1 3.2.3.1. Классификация функций ......................... 1 3.2.3.2. Скалярные функции ................................. 3 3.2.3.3. Агрегатные функции ............................. 39 3.2.3.4. Функции для списка выражений .......... 42 3.2.3. Функции в SQL 3.2.3.1. Классификация функций Функции в SQL подобны любым другим запросам языка в том смысле, что они производят действия с данными и возвращают результат в качестве своего значения. В СУБД обычно имеется 3 основных класса функций: встроенные, определяемые пользователем и хранимые (процедурные). Встроенными являются функции, предопределенные в языке SQL конкретной СУБД. В SQL определено множество встроенных функций различных категорий [39, 40, 42, 44, 48]. Эти функции делятся на основные группы: 1) скалярные функции; 2) агрегатные функции; 3) функции для списка значений; 4) функции выбора вариантов; 5) оконные (аналитические) функции. Скалярные функции (их еще называют однострочными) обрабатывают одиночное значение и возвращают также одно значение. Скалярные функции разрешается использовать везде, где допускается применение выражений. Скалярные функции бывают следующих категорий:  строковые функции, которые выполняют определенные действия над строками и возвращают строковые или числовые значения (для Oracle здесь среди прочих можно отдельно выделить группу функций регулярных выражений);  числовые функции, которые возвращают числовые значения на основании заданных в аргументе значений того же типа;  функции времени и даты, которые выполняют различные действия над входными значениями времени и даты и возвращают строковое, числовое значения или значение в формате даты и времени;  функция преобразования типа. Агрегатные функции используются для получения обобщающих значений. Они, в отличие от скалярных функций, оперируют значениями столбцов множества строк. К агрегатным функциям относятся такие функции, как SUM, вычисляющая итог, MAX и MIN, возвращающие 1 соответственно наибольшее и наименьшее значения, AVG, вычисляющая среднее значение, и COUNT, вычисляющая количество значений в столбце. Функции для списка значений используются для обработки значений, заданных в списке аргументов. В Firebird такие функции представлены тремя функциями – MAXVALUE, MINVALUE и LIST. Функции MAXVALUE и MINVALUE в чем-то похожи на агрегатные функции MAX и MIN, однако выбирают максимальное и минимальное значения не из множества значений строк в одном столбце, а из значений, заданных в списке аргументов. Функция LIST объединяет обрабатываемые значения в единую строку. В Oracle функции для списка значений представлены двумя функциями – GREATEST и LEAST. Функция GREATEST возвращает наибольшее значение в списке выражений, функция LEAST возвращает наименьшее значение в списке выражений. Применительно к Oracle в отдельную группу могут быть выделены появившиеся в Oracle Database 10g функции регулярных выражений, которые значительно увеличивают возможности поиска символьных данных и манипулирования ими. Среди таких функций следующие:  REGEXP_LIKE – предикат, используемый в секции WHERE или же при определении ограничения на таблицу;  REGEXP_INSTR – возвращает позицию символа, находящегося в начале или конце соответствия для шаблона;  REGEXP_SUBSTR – возвращает подстроку, которая соответствует шаблону;  REGEXP_REPLACE – возвращает измененную входную строку, в которой все вхождения шаблона заменены заданным значением. Особое место среди встроенных скалярных функций языка SQL занимают функции выбора вариантов, которые являются разновидностью CASEвыражений. В качестве функций выбора вариантов используются функции COALESCE, NULLIF, DECODE, в Firebird и MS SQL Server также IIF. Возвращаемый этими функциями результат меняется в зависимости от значения, которое обрабатывается функцией. Оконные (аналитические) функции предназначены для статистического анализа данных в готовой выборке. Это достаточно мощный и удобный инструмент, который присутствует во многих СУБД. Например, в Oracle оконные функции поддерживаются, начиная с версии 8i, в MS SQL Server – начиная с версии 2005, в Firebird оконные функции появились только в версии 3.0. Существует несколько типов аналитических функций: 1) агрегатные функции; 2) функции ранжирования; 3) навигационные функции. Оконные функции будут подробно рассмотрены в п. 3.2.7 после изучения секций GROUP BY и ORDER BY, так как для понимания алгоритмов работы 2 аналитических функций необходимо понимание работы запросов с группировкой и сортировкой. Функции, определяемые пользователем (User Defined Function, UDF), являются вспомогательными программами, написанными на языке программирования, таком как C, C++ или Pascal, и компилированными как совместно используемые двоичные библиотеки – DLL [29]. Внешние функции можно использовать в выражениях, так же как и встроенные функции SQL. Как и встроенные функции, они могут возвращать значения для переменных или выражений SQL в хранимых процедурах и триггерах. СУБД Firebird, например, поставляет две готовые к использованию библиотеки UDF: Ib_Udf и FbUdf. Firebird загружает UDF из библиотек, находящихся в каталоге Udf каталога инсталляции или в других каталогах, указанных в параметре UdfAccess в файле конфигурации Firebird. Когда пользовательская функция написана, компилирована и инсталлирована в соответствующий каталог на сервере, она должна быть объявлена для БД, чтобы ее можно было использовать как функцию SQL. Для объявления внешней функции используется оператор DECLARE EXTERNAL FUNCTION. Можно объявить функцию также с использованием любого интерактивного инструмента SQL или скрипта. После того как функция будет объявлена для любой БД на сервере, содержащая ее библиотека будет загружаться при первом же обращении приложения к любой функции, включенной в эту библиотеку. Необходимо объявить каждую функцию, которую нужно использовать, для каждой БД, которая будет использоваться. Хранимые функции являются подпрограммами, написанными на процедурном языке СУБД. Такие функции обычно создаются для реализации бизнес-логики и являются самостоятельным объектом БД. Хранимые функции будут описаны в п. 6.3 при изучении процедурных языков. Рассмотрим подробнее различные виды встроенных функций СУБД Firebird 3.0, Oracle 11.2 XE и MS SQL Server 2014, познакомимся с правилами работы с функциями в этих СУБД на примерах. 3.2.3.2. Скалярные функции Строковые функции. Эти функции используют в качестве аргумента строку символов, а в качестве результата возвращают также символьную строку или числовое значение. Для выделения подстроки указанной длины из строкового выражения, начиная с заданной позиции, в Firebird и MS SQL Server используется функция SUBSTRING. В Firebird функция имеет формат SUBSTRING (строковое_выражение FROM позиция [FOR длина]), а в MS SQL Server SUBSTRING(строковое_выражение, позиция [, длина]). 3 Здесь позиция – позиция, начиная с которой выполняется выделение, например 1 для первого символа в строке; длина – количество выделяемых символов. Если длина не задана, то выделение производится до конца исходной строки. Задание отрицательного значения длины приводит к тому, что символы отсчитываются от конца строки, а не от начала. Задание длины, превышающей по абсолютному значению длину строки, приводит к тому, что функция возвращает NULL. Например, для вывода номеров лицевых счетов абонентов и первых трех символов их ФИО (рис. 3.21) в Firebird можно использовать запрос SELECT A.AccountCD, SUBSTRING (A.Fio FROM 1 FOR 3) AS "Fio3" FROM Abonent A;, а в MS SQL Server запрос SELECT AccountCD, SUBSTRING(Fio, 1, 3) AS "Fio3" FROM ABONENT; Следует учесть, что тип значений ACCOUNTCD Fio3 столбца Fio3 будет такой же, как и тип 005488 Акс первого аргумента (строковое 115705 Мищ выражение, из которого выделяются 015527 Кон символы). Так как ширина столбца Fio 443690 Тул таблицы Abonent равна 30 136159 Сви [VARCHAR(30)], то столбец Fio3 443069 Ста будет иметь также ширину 30, а не 3. Надо отметить, что в качестве 136160 Шма аргументов SUBSTRING могут 126112 Мар использоваться подзапросы, 136169 Ден возвращающие единственное 080613 Лук значение (<скалярный_подзапрос>). 080047 Шуб 080270 Тим Рис. 3.21. Результат работы функции SUBSTRING В качестве аргументов позиция и длина в SUBSTRING можно использовать и выражения (в том числе со скалярными функциями, возвращающими числовой результат). В Oracle вместо функции SUBSTRING используется аналогичная функция SUBSTR, имеющая формат SUBSTR(строковое_выражение, позиция [, длина]). Например, предыдущий запрос в Oracle должен быть записан так: SELECT A.AccountCD, SUBSTR(A.Fio, 1, 3) AS "Fio3" 4 FROM Abonent A; Следует отдельно отметить, что в Firebird 3.0 существует возможность использования функции SUBSTRING с регулярными выражениями [42, 43]. При этом функция имеет следующий формат: SUBSTRING (строковое_выражение SIMILAR '<регулярное_выражение>' ESCAPE 'символ_пропуска'), где <регулярное_выражение> ::= <шаблон1>символ_пропуска"<шаблон2>символ_пропуска"<шаблон3>. В таком формате функция SUBSTRING возвращает часть строки из строкового выражения, соответствующую регулярному выражению в предложении SIMILAR. Возвращаемое значение соответствует части <шаблон2> регулярного выражения, и для этого значения истинно выражение <значение> SIMILAR TO <шаблон1> || <шаблон2> || <шаблон3> ESCAPE символ_пропуска. Регулярные шаблоны составляются в соответствии с правилами, описанными в разд. 3.2.2.12. Если соответствие не установлено, возвращается значение NULL. Например, запрос вида SELECT SUBSTRING('abcabc' SIMILAR '_#"%#"_' ESCAPE '#') FROM RDB$DATABASE; вернет строку 'bcab', а запрос вида SELECT SUBSTRING('abcabc' SIMILAR '#"(abc)*#"' ESCAPE '#') FROM RDB$DATABASE; вернет строку вида 'abcabc'. Для вывода строки в обратной последовательности (начиная с конца) используется функция REVERSE. Функция имеет формат REVERSE (строковое_ выражение). Например, для вывода информации об абонентах, имеющих инициалы E.B. (рис. 3.22), можно использовать запрос SELECT * FROM Abonent WHERE REVERSE (Fio) STARTING WITH REVERSE ('Е.В.'); ACCOUNTC D 115705 STREETC D 3 HOUSEN O 1 FLATN O 82 443069 4 51 55 FIO Мищенко Е.В. Стародубце в Е.В. PHON E 769975 683014 Рис. 3.22. Результат работы функции REVERSE Функция REVERSE используется в Firebird и MS SQL Server, а в Oracle отсутствует. 5 Функции LEFT и RIGHT используются для выделения нужного количества символов соответственно из начала или конца определенной строки и имеют формат LEFT (строковое_выражение, длина), RIGHT (строковое_выражение, длина), где строковое_выражение – выражение, из которого будут выделяться символы; длина – количество выделяемых символов в начале (для LEFT) или в конце (для RIGHT) строки. Например, предыдущий запрос, реализованный с помощью функции REVERSE, можно реализовать с помощью функции RIGHT таким образом: SELECT * FROM Abonent WHERE RIGHT (Fio, 4) = 'Е.В.'; Результат выполнения запроса будет совпадать с результатом, представленным на рис. 3.22. Например, для вывода Fio абонентов, проживающих на улице с кодом 3, и первых 4-х цифр из номеров их лицевых счетов можно использовать запрос SELECT Fio, LEFT (AccountCD, 4) FROM Abonent WHERE StreetCD = 3; Результат выполнения запроса представлен на рис. 3.23. FIO LEFT Аксенов С.А. 0054 Мищенко Е.В. 1157 Конюхов В.С. 0155 Рис. 3.23. Результат работы функции LEFT Функции LEFT и RIGHT используются в Firebird и MS SQL Server, а в Oracle отсутствуют. Существует ряд функций для замены части исходной строки на другую последовательность символов. Функция OVERLAY заменяет в исходной строке подстроку, начинающуюся с номера позиция и имеющую размер длина, на значение строки для замены. Функция имеет формат OVERLAY ( исходная_строка PLACING строка_для_замены FROM позиция [ FOR длина ] ), где исходная_строка и строка_для_замены могут представлять собой строковое выражение. Если длина не указана, то по умолчанию принимается длина в символах строки для замены. Например, если требуется вывести номера телефонов абонентов с заменой первых 2-х цифр на '66', в Firebird можно использовать запрос SELECT OVERLAY (Phone PLACING '66' FROM 1) FROM Abonent; Функция OVERLAY эквивалентна следующему выражению с использованием функции SUBSTRING: SUBSTRING (исходная_строка FROM 1 FOR (позиция – 1)) 6 || строка_для_замены || SUBSTRING (исходная_строка FROM (позиция + длина)). Функция OVERLAY используется только в Firebird, в MS SQL Server и Oracle отсутствует. В MS SQL Server поддерживается функция STUFF, аналогичная функции OVERLAY. Функция STUFF вставляет одну строку в другую, удаляя указанное количество символов первой строки в начальной позиции и вставляя на их место вторую строку [37]. Функция имеет следующий синтаксис: STUFF (исходная_строка, позиция, длина, строка_для_замены) Если начальная позиция или число удаляемых символов отрицательны или если начальная позиция превышает длину первой строки, возвращается пустая строка. Если начальная позиция равна 0, то возвращается значение NULL. Если число удаляемых символов превышает длину первой строки, удаление выполняется до первого символа первой строки. Например, предыдущий запрос по выводу измененных тебефонов номеров абонентов реализовать в MS SQL Server можно так: SELECT STUFF (Phone, 1, 2, '66') FROM Abonent; Функция REPLACE заменяет все вхождения подстроки в строковое выражение на указанную строку для замены. Имеет формат, одинаковый для Firebird, MS SQL Server и Oracle: REPLACE (строковое_выражение, подстрока, строка_для_замены). Например, для замены в названии неисправностей слова «плиты» на словосочетание «газовой плиты» (рис. 3.24) можно выполнить запрос SELECT REPLACE (FailureNM, 'плиты', 'газовой плиты') FROM Disrepair; REPLACE Засорилась водогрейная колонка Не горит АГВ Течет из водогрейной колонки Неисправна печная горелка Неисправен газовый счетчик Плохое поступление газа на горелку газовой плиты Туго поворачивается пробка крана газовой плиты При закрытии краника горелка газовой плиты не гаснет Неизвестна Рис. 3.24. Результат работы функции REPLACE 7 Следует отметить, что в Oracle возвращаемый предыдущим запросом столбец будет иметь имя, включающее в себя не только название функции, но и ее аргументы: REPLACE(FAILURENM,'ПЛИТЫ','ГАЗОВОЙПЛИТЫ'). Функция TRIM возвращает строку аргумента, удаляя символы (по умолчанию – пробелы) из начала и/или конца строки. Для вызова функции в стандарте SQL используется синтаксис TRIM ( [ [LEADING | TRAILING | BOTH ] [ удаляемая_подстрока ] FROM ] строковое_выражение). LEADING указывает на то, что надо удалить указанную подстроку из начала строки, TRAILING – из конца строки, BOTH – из начала и конца строки. При использовании функции следует учитывать:  если LEADING, TRAILING или BOTH не указаны, то принимается BOTH по умолчанию;  если удаляемая подстрока не определена, то принимается по умолчанию пробел;  если LEADING, или TRAILING, или BOTH и/или удаляемая подстрока указаны, то после слова FROM должно быть обязательно указано строковое_выражение, из которого удаляются символы;  указание строки, из которой удаляются символы, после слова FROM не может быть использовано самостоятельно (если LEADING, TRAILING, BOTH и удаляемая_подстрока не указаны). Например, для вывода данных из таблицы Street, указывая название улицы без слова «УЛИЦА» (рис. 3.25), можно использовать запрос: SELECT StreetCD, TRIM (BOTH 'УЛИЦА' FROM StreetNM) AS "Str_Name” FROM Street; STREETCD 3 7 6 8 4 5 1 2 Str_Name ВОЙКОВ ПЕРЕУЛОК КУТУЗОВА МОСКОВСКАЯ МОСКОВСКОЕ ШОССЕ ТАТАРСКАЯ ГАГАРИНА ЦИОЛКОВСКОГО НОВАЯ Рис. 3.25. Результат работы функции TRIM Например, для вывода лицевых счетов абонентов без нулей слева (рис. 3.26) можно использовать запрос: SELECT TRIM(LEADING '0' FROM AccountCD) AS AccountCD, Fio 8 FROM Abonent; ACCOUNTCD 5488 115705 15527 443690 136159 443069 136160 126112 136169 80613 80047 80270 FIO Аксенов С.А. Мищенко Е.В. Конюхов В.С. Тулупова М.И. Свирина З.А. Стародубцев Е.В. Шмаков С.В. Маркова В.П. Денисова Е.К. Лукашина Р.М. Шубина Т.П. Тимошкина Н.Г. Рис. 3.26. Результат работы функции TRIM (удаление символов слева) Функция TRIM поддерживается в формате, определяемым стандартом, СУБД Firebird и Oracle. В Oracle также определены функции LTRIM и RTRIM. Функции LTRIM и RTRIM удаляют заданную подстроку из начала или конца заданной строки соответственно и имеют следующий формат: LTRIM(строковое_выражение [, удаляемая_подстрока]); RTRIM(строковое_выражение [, удаляемая_подстрока]). Например, приведенный выше запрос на вывод названий улиц без слова «УЛИЦА» в Oracle можно реализовать с помощью функции RTRIM: SELECT StreetCD, RTRIM(StreetNM, 'УЛИЦА') AS "Str_Name" FROM Street; Результат выполнения запроса будет совпадать с результатом, приведенным на рис. 3.25. MS SQL Server поддерживает функции LTRIM и RTRIM в упрощенном варианте: функции имеют синтаксис LTRIM(строковое_выражение); RTRIM(строковое_выражение); и используются только для удаления начальных или конечных пробелов. Чтобы удалить начальные и конечные пробелы, нужно к строке применить обе функции LTRIM() и RTRIM(). При указании удаляемой подстроки в функциях TRIM, RTRIM и LTRIM следует учитывать регистр символов (строчные или прописные буквы). Если в предыдущем примере вместо 'УЛИЦА' ввести 'улица', то запрос выдаст неверный результат, так как все названия улиц в таблице Street записаны в верхнем регистре символов. 9 Существуют функции LPAD и RPAD, которые дополняют строку аргумента слева (LPAD) или справа (RPAD) указанной последовательностью символов: строка_заполнитель до заданного размера длина. В случае если строка_заполнитель не указана, для дополнения используется пробел. Строка_заполнитель обрезается, когда результирующая строка достигает заданной длины. Функции имеют следующий формат: LPAD( строковое_выражение, длина [, строка_заполнитель ] ), RPAD( строковое_выражение, длина [, строка_заполнитель ] ). Например, требуется вывести номера лицевых счетов абонентов и Fio, дополненные справа знаком звездочки (*) до длины 20 символов (рис. 3.27). Запрос будет выглядеть таким образом: SELECT AccountCD, RPAD (Fio, 20,'*') FROM Abonent; ACCOUNTCD 005488 136169 015527 080613 126112 115705 136159 443069 080270 443690 136160 080047 RPAD Аксенов С.А.******** Денисова Е.К.******* Конюхов В.С.******** Лукашина Р.М.******* Маркова В.П.******** Мищенко Е.В.******** Свирина З.А.******** Стародубцев Е.В.**** Тимошкина Н.Г.****** Тулупова М.И.******* Шмаков С.В.********* Шубина Т. П.********* Рис. 3.27. Результат работы функции RPAD Функции LPAD и RPAD используются в Firebird и Oracle, а в MS SQL Server не поддерживаются. В Oracle столбец вышеприведенного запроса с результатом работы функции будет иметь имя не RPAD, а RPAD (FIO, 20,'*'). В Oracle и MS SQL Server для получения строки, являющейся результатом объединения двух или более строковых значений, может использоваться функция CONCAT [37, 49]. Функция фактически является аналогом операции конкатенации и имеет следующий синтаксис: CONCAT (строковое_выражение1, строковое_выражение2 [,строковое_выражениеN ]). CONCAT принимает переменное количество строковых аргументов и объединяет их в одну строку. Для этого требуется не менее двух входных значений, в противном случае возникает ошибка. Все аргументы неявно преобразуются в строковые типы и затем объединяются. Значения NULL неявно преобразуются в пустую строку. Если все аргументы имеют значение 10 NULL, то возвращается пустая строка типа VARCHAR(1). Неявное преобразование в строки выполняется по существующим в СУБД правилам преобразования типов данных. Например, запрос с конкатенацией ФИО и номеров телефонов абонентов (рис. 3.4), приведенный ранее в п. 3.2.1, в MS SQL Server может быть реализован с помощью функции CONCAT так: SELECT AccountCD AS "AccountCDRyazan", CONCAT (Fio, ' имеет телефон ', '8-4912-', Phone) "ФИО+телефон" FROM Abonent; Функция REPLICATE в MS SQL Server повторяет значение строки указанное число раз. Функция имеет формат REPLICATE ( строковое_выражение, числовое_выражение ), где числовое_выражение – выражение любого целого типа, задающее число повторов. Если числовое_выражение имеет отрицательное значение, то возвращается NULL. Существуют функции, которые выполняют преобразования между регистрами символов. Функция UPPER преобразует все символы строки в верхний регистр и имеет синтаксис UPPER (<значение>), где <значение> – преобразуемый столбец, переменная или выражение строкового типа. Если набор символов и последовательность сортировки поддерживают преобразование в верхний регистр (например, WIN1251), то функция возвращает строку, в которой все символы преобразованы в верхний регистр. Строка имеет ту же длину, что и входное <значение>. Для наборов символов, не поддерживающих преобразование в верхний регистр (в частности, кодировка по умолчанию NONE), функция возвращает неизменное входное значение. Следующий запрос выводит названия услуг заглавными буквами (рис. 3.28): SELECT UPPER(ServiceNM) FROM Services; UPPER ГАЗОСНАБЖЕНИЕ ЭЛЕКТРОСНАБЖЕНИЕ ТЕПЛОСНАБЖЕНИЕ ВОДОСНАБЖЕНИЕ Рис. 3.28. Результат работы функции UPPER Противоположной является функция LOWER, которая преобразует все символы строки в нижний регистр: LOWER (<значение>), где <значение> – преобразуемый столбец, переменная или выражение строкового типа. Функции UPPER, LOWER используются в Firebird, Oracle, MS SQL Server. 11 В Oracle также поддерживается функция INITCAP, которая преобразует первую букву каждого слова в заглавную, а остальные буквы – в строчные. Функция имеет следующий синтаксис: INITCAP(<значение>), где <значение> – преобразуемый столбец, переменная или выражение строкового типа. Существуют функции для определения символа по известному коду. Для Firebird – это функция ASCII_CHAR, для Oracle – функция CHR, для MS SQL Server – функция CHAR. Функции имеют синтаксис ASCII_CHAR (код_символа), CHR (код_символа), CHAR (код_символа). Например, запрос для определения символа с кодом 82 в Firebird SELECT ASCII_CHAR(82) FROM RDB$DATABASE; или в Oracle SELECT CHR(82) FROM DUAL; или в MS SQL Server SELECT CHAR(82); Код должен лежать в диапазоне от 0 до 255. При работе с Oracle Database 11g Express Edition дополнительно следует учесть, что БД создается по умолчанию с набором символов AL32UTF8, а функция CHR возвращает символ, имеющий заданный код в наборе символов БД. При попытке получить функцией CHR символ по коду более 193 в БД с кодировкой AL32UTF8 Oracle вернет ошибку. Функции ASCII_CHAR, CHR и CHAR могут использоваться для вставки управляющих символов в символьные строки. Рассмотренные выше строковые функции возвращают результат в виде строки символов. Существует также ряд строковых функций, которые в качестве результата возвращают числовое значение. Среди них функции, обратные предыдущим описанным, для определения кода символа (крайнего левого) в указанной строке. В Firebird используется функция ASCII_VAL, в Oracle и MS SQL Server – это функция ASCII. Функции имеют следующий синтаксис: ASCII_VAL (строка) , ASCII (строка). Например, запрос в Firebird, определяющий код символа «R»: SELECT ASCII_VAL('Ready') FROM RDB$DATABASE; Аналогичный ему запрос в Oracle: SELECT ASCII ('R') FROM DUAL; и в MS SQL Server SELECT ASCII ('Ready'); Функции вернут NULL, если указана пустая строка. Для определения позиции первого вхождения заданной подстроки в строку в Firebird можно использовать функцию POSITION: 12 POSITION (подстрока IN строковое_выражение) . Функция возвращает ноль, если подстрока отсутствует внутри строки. Например, для вывода номеров лицевых счетов и ФИО тех абонентов, у которых в фамилиях вторая буква «у» (рис. 3.29), можно использовать запрос SELECT AccountCD, Fio FROM Abonent WHERE POSITION ('у' IN Fio) = 2; ACCOUNTCD FIO 443690 Тулупова М.И. 080613 Лукашина Р.М. 080047 Шубина Т. П. Рис. 3.29. Результат работы функции POSITION В Oracle существует аналогичная функция INSTR, которая возвращает позицию вхождения подстроки в строку, начиная с позиции n и количества вхождений этой подстроки m. Функция имеет синтаксис INSTR(строковое_выражение, подстрока [,n [,m]]), где n – положение символа в строке, с которого начнется поиск, а m – n-е вхождение подстроки [49]. Если параметр n опущен, то он по умолчанию равен 1. Если параметр n отрицательный, то функция INSTR рассчитывает позицию n в обратном направлении от конца строки, а затем выполняет поиск по направлению к началу строки. Если параметр m опущен, то он по умолчанию равен 1. В MS SQL Server для определения позиции вхождения подстроки в строку используются функции CHARINDEX и PATINDEX. Функция CHARINDEX ищет в выражении другое выражение и возвращает его начальную позицию, если оно найдено. Функция имеет синтаксис CHARINDEX (подстрока, строковое_выражение [, n ]), где n – позиция, с которой начинается поиск. Если n не указано, имеет отрицательное значение или равно нулю, то поиск начинается с начала строкового выражения. Функция PATINDEX для любого допустимого символьного или текстового типа данных возвращает начальную позицию первого вхождения шаблона в указанном выражении или ноль, если шаблон не найден. Функция имеет синтаксис PATINDEX (шаблон_поиска, строковое_выражение), где шаблон_поиска задается по общим правилам задания шаблонов. В любой СУБД существуют функции для определения размера строки. В Firebird для этого применяются функции BIT_LENGTH, CHAR[ACTER]_LENGTH, OCTET_LENGTH. Функция BIT_LENGTHB возвращает длину строки в битах, функция CHAR[ACTER]_LENGTH – в символах, а функция OCTET_LENGTH – в байтах. Эти три функции имеют одинаковый синтаксис { BIT_LENGTH | CHAR[ACTER]_LENGTH | OCTET_LENGTH } ( строковое_выражение ). Например, вывести названия услуг и длины названий в символах и в байтах (рис. 3.30) можно с помощью запроса 13 SELECT ServiceNM, CHAR_LENGTH (ServiceNM), BIT_LENGTH (ServiceNM) FROM Services; SERVICENM Газоснабжение Электроснабжение Теплоснабжение Водоснабжение CHAR_LENGTH 13 16 14 13 BIT_LENGTH 104 128 112 104 Рис. 3.30. Результаты работы функций CHAR_LENGTH и BIT_LENGTH Проверить, что тип VARCHAR предусматривает автоматическое отбрасывание символов пробела (рис. 3.31), можно в Firebird с помощью следующего запроса, использующего функции CHAR_LENGTH и TRIM: SELECT FIRST 3 FailureNM AS "FailureNM", CHAR_LENGTH (FailureNM), CHAR_LENGTH (TRIM(FailureNM)) FROM Disrepair; FailureNM Засорилась водогрейная колонка Не горит АГВ Течет из водогрейной колонки CHAR_LENGTH CHAR_LENGTH1 30 30 12 12 28 28 Рис. 3.31. Результат работы функции CHAR_LENGTH Во втором столбце выводятся длины значений столбца FailureNM в символах, а в третьем – длины значений этого же столбца, но с удаленными символами пробелов. Можно заметить, что значения во втором и третьем столбце совпадают, так как тип столбца FailureNM – VARCHAR(50) и символы пробелов автоматически отбрасываются. Рассмотрим пример запроса, позволяющего подсчитать, сколько раз символ или подстрока встречается в заданной строке. Для подсчета количества букв 'и' в ФИО абонентов можно использовать такой запрос: SELECT Fio, 'и', (CHAR_LENGTH(Fio) – CHAR_LENGTH(REPLACE(Fio,'и','')))/CHAR_LENGTH('и') FROM Abonent; В этом запросе при вычитании из длины строки длины строки без подстроки получается разница, которая соответствует количеству букв "и" в ФИО. Последней операцией является деление на длину строки поиска. Эта операция необходима, если длина искомой строки более 1 символа. В Oracle существуют аналогичные функции LENGTH и LENGTHB. Функция LENGTH возвращает длину строки в символах, а функция LENGTHB – в байтах. Функции имеют синтаксис { LENGTH | LENGTHB } ( строковое_выражение ). Например, вышеприведенный запрос на вывод длины названий услуг в символах и в байтах в Oracle может быть записан так: SELECT ServiceNM, LENGTH(ServiceNM), LENGTHB(ServiceNM) 14 FROM Services; В MS SQL Server для определения длины строки используются функции LEN и DATALENGTH. Функции имеют формат { LEN | DATALENGTH } ( строковое_выражение ). Функция LEN возвращает количество символов указанного строкового выражения, исключая конечные пробелы, а функция DATALENGTH возвращает число байтов, использованных для представления выражения. Для преобразования значения уникального идентификатора (UUID) между двоичным и строковым видами в Firebird используются функции CHAR_TO_UUID и UUID_TO_CHAR. Функция CHAR_TO_UUID преобразует строковое (CHAR(32) кодировки ASCII) представление UUID (вида XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) в двоичное (CHAR(16) кодировки OCTETS), более оптимизированное для хранения. Функция UUID_TO_CHAR выполняет обратное преобразование, т. е. преобразует двоичный UUID, полученный обычно с помощью функции GEN_UUID (см. табл. 3.4), в строковый. Функции имеют формат CHAR_TO_UUID (строковое_выражение), UUID_TO_CHAR (строковое_выражение). Например, можно использовать следующие запросы: SELECT CHAR_TO_UUID ('93519227-8D50-4E47-81AA-8F6678C096A1') FROM RDB$DATABASE; или SELECT UUID_TO_CHAR (GEN_UUID()) FROM RDB$DATABASE; В заключение описания строковых функций рассмотрим 2 системные функции Firebird, позволяющие получать информацию о параметрах БД, о текущем подключении и транзакции, а также параметры действия триггеров DDL: RDB$GET_CONTEXT и RDB$SET_CONTEXT [42, 44]. Синтаксис функции RDB$GET_CONTEXT RDB$GET_CONTEXT ('<пространство_имен>', '<переменная>'), где <пространство_имен> ::= { SYSTEM | DDL_TRIGGER | USER_SESSION | USER_TRANSACTION }, <переменная> – регистрозависимая строка длиной до 80 символов. Функция RDB$GET_CONTEXT возвращает значение контекстной переменной из пространств имен SYSTEM, DDL_TRIGGER, USER_SESSION, USER_TRANSACTION. Пространство имен и имя переменной – это строковые выражения, которые чувствительны к регистру и должны быть отличны от NULL. Если в указанном пространстве есть запрашиваемая переменная, будет возвращено ее значение типа VARCHAR(255). Если указано несуществующее пространство имен или указано пространство имен SYSTEM или DDL_TRIGGER, но запрашиваемая переменная в нем не существует, будет сгенерирована ошибка. Если запрашивается несуществующая переменная в другом пространстве имен, функция вернет NULL. Пространство имен SYSTEM доступно только для чтения и содержит предустановленные переменные, которые приведены в табл. 3.2. 15 Таблица 3.2. Контекстные переменные в пространстве имен SYSTEM Переменная Описание ENGINE_VERSION Возвращает текущую версию SQL-сервера. Например: '2.5.0' NETWORK Сетевой протокол, используемый клиентом в _PROTOCOL текущем соединении с БД. Может иметь значения 'TCPv4', 'WNET', 'XNET' или NULL CLIENT_ADDRESS Сетевой адрес клиента. Для протокола TCPv4 содержит IP-адрес. Для протокола XNET содержит ID локального процесса. Для всех остальных протоколов содержит NULL DB_NAME Имя БД, в зависимости от подключения возвращает алиас или путь к файлу, указанные в строке подключения к БД ISOLATION_LEVEL Уровень изоляции текущей транзакции. Может иметь значения 'READ, COMMITTED', 'SNAPSHOT' или 'CONSISTENCY' TRANSACTION_ID Номер текущей транзакции (значение идентично переменной CURRENT_TRANSACTION) SESSION_ID Номер текущего подключения (значение идентично переменной CURRENT_CONNECTION) CURRENT_USER Текущий пользователь (значение идентично переменной CURRENT_USER) CURRENT_ROLE Текущая роль (значение идентично переменной CURRENT_ROLE) Например, получить текущую версию SQL-сервера Firebird можно с помощью запроса SELECT RDB$GET_CONTEXT ('SYSTEM', 'ENGINE_VERSION') FROM RDB$DATABASE; Пространство имен DDL_TRIGGER доступно только для чтения и содержит предустановленные переменные, которые приведены в табл. 3.3. Значения переменных доступны только в процессе работы триггера DDL (триггеры DDL и примеры использования функций с пространством имен DDL_TRIGGER будут подробно рассмотрены в разд. 6.6.2). Таблица 3.3. Контекстные переменные в пространстве имен DDL_TRIGGER Переменная Описание EVENT_TYPE Тип события: CREATE, ALTER, или DROP OBJECT_TYPE Тип объекта БД (TABLE, VIEW и т. д.) DDL_EVENT Событие DDL в виде EVENT_TYPE || ' ' || OBJECT_TYPE 16 OBJECT_NAME Наименование объекта метаданных SQL_TEXT Текст SQL-запроса Пространства имен USER_SESSION и USER_TRANSACTION изначально пустые и не содержат переменных. Пользователь может создавать переменные и задавать им значения с помощью функции RDB$SET_CONTEXT(), а потом получить их значение с помощью функции RDB$GET_CONTEXT(). Функция RDB$SET_CONTEXT имеет синтаксис: RDB$SET_CONTEXT ('<пространство_имен>', '<переменная>', {<значение> | NULL}), где <пространство_имен> ::= { USER_SESSION | USER_TRANSACTION }; <переменная> – чувствительная к регистру строка длиной до 80 символов; <значение> – любое выражение, приводимое к типу VARCHAR(255). Функция RDB$SET_CONTEXT создает, задает или удаляет значение контекстной переменной в пространствах имен USER_SESSION и USER_TRANSACTION. При этом следует помнить, что максимальное количество переменных в любом контексте (транзакции или соединения) равно 1000. Переменные пространства имен USER_SESSION привязаны к текущему соединению, а переменные пространства имен USER_TRANSACTION существуют в контексте транзакции, в которой были созданы. Когда транзакция завершается, все созданные в ней переменные уничтожаются. Функция RDB$SET_CONTEXT возвращает результат типа INTEGER: 1, если переменная уже существует, и 0, если переменная еще не была создана. Чтобы удалить переменную, необходимо установить ее значение в NULL. Установим, например, в пределах текущего подключения значение пользовательской переменной MyVar в значение 86, а затем получим значение данной переменной. Запросы для выполнения указанных действий будут выглядеть следующим образом: SELECT RDB$SET_CONTEXT('USER_SESSION','MyVar',86) FROM RDB$DATABASE; SELECT RDB$GET_CONTEXT('USER_SESSION',' MyVar') FROM RDB$DATABASE; Функции RDB$SET_CONTEXT() и RDB$GET_CONTEXT() являются встроенными, но представляют собой подобие «предекларированных UDFфункций», хотя и находятся не во внешней библиотеке. Это сделано для возможности использовать их как UDF-функции – например, вызывать как процедуры в PSQL: New.UserAddr := RDB$GET_CONTEXT ('SYSTEM', 'CLIENT_ADDRESS'); С обычными встроенными функциями это невозможно. В MS SQL Server существуют так называемые функции конфигурации, которые позволяют получить сведения о текущих значениях параметров конфигурации [37]. Имена таких функций начинаются с символов @@, и все они являются недетерминированными, то есть данные функции не всегда возвращают одинаковый результат даже при одних и тех же входных 17 значениях. Например, следующий запрос возвращает сведения о версии текущего экземпляра MS SQL Server: SELECT @@VERSION AS 'SQL Server Version'; Также в MS SQL Server доступен ряд других системных функций для получения информации об объектах и параметрах БД. Числовые функции. Эти функции возвращают числовые значения на основании значений того же типа, заданных в аргументе. Числовые функции используются для обработки данных, а также в условиях поиска. Стандартные числовые функции СУБД перечислены в табл. 3.4 [28, 29, 37, 42, 49]. Таблица 3.4. Числовые функции Функци Описание Функция Oracle Функция MS я SQL Server Firebird RAND() Случайное число от 0 до 1 Нет RAND() ABS Абсолютное значение ABS (число) ABS (число) (число) SIGN Знаковая функция (возвращает SIGN (число) SIGN (число) (число) 1 для положительного числа, 0 – для нуля, -1 – для отрицательного числа) MOD Остаток от деления MOD (делимое, (делимое % (делимо делитель); делитель) е, REMAINDER делител (делимое, делитель) ь) Функция REMAINDER использует в своей формуле функцию ROUND, тогда как функция MOD использует функцию FLOOR в своей формуле LOG Логарифм числа по LOG (основание, LOG (число [, (основан указанному основанию число) основание]) ие, число) LN Натуральный логарифм числа LN (число) LOG (число) (число) LOG10 Десятичный логарифм числа Нет LOG10 (число) (число) 18 EXP (число) PI() POWER (число, степень) SQRT (число) FLOOR (число) CEIL | CEILIN G (число) Экспоненциальная функция (e EXP (число) в степени аргумента) Константа π = 3.1459… Нет POWER (число, Возведение числа в степень степень) Квадратный корень SQRT (число) Округление до целого числа вниз Округление до целого числа вверх FLOOR (число) CEIL (число) EXP (число) PI() POWER (число, степень) SQUARE (число) FLOOR (число) CEILING (число) Продолжение табл. 3.4 19 ROUN D (выраж ение, точност ь) Округление ROUND числа (выражение, <выражение> до точность) <точность> знаков после запятой в ближайшую сторону. Если число знаков отрицательное, то округление идет до <точность> знаков перед запятой ROUND (выражение, точность [, признак]) Если "признак" равен нулю или отсутствует, то выполняется обычное округление. Если "признак" имеет положительн ое значение, то результат округляется до соответствую щего количества знаков после десятичной точки. Если "признак" отрицательны й, то указанное количество знаков целого справа обнуляется, точнее, происходит округление числа до знака = "признак" + 1 20 Округление до указанного количества знаков <точность> после запятой в меньшую по модулю сторону. Если число знаков отрицательное, то округление идет до <точность> знаков перед запятой GEN_I Генерация D () уникального значения GEN_U Генерация UID () уникального значения в кодировке OCTETS HASH Хэш-функция (значен (рандомизация ие) значения) TRUNC (число, точност ь) SIN (число) SINH (число) TRUNC (число, точность) Нет Нет Нет Нет Нет ORA_HASH Нет (значение, [макс_значени е], [начальное_зн ачение]) Продолжение табл. 3.4 Тригонометрические функции Синус (аргумент SIN (число) SIN (число) задается в радианах) Гиперболический SINH Нет синус числа, (число) выраженный в радианах 21 COS (число) COSH (число) TAN (число) TANH (число) COT (число) ASIN (число) Косинус (угол определяется в радианах, результат в диапазоне от -1 до 1) Гиперболический косинус числа, выраженный в радианах Тангенс (аргумент задается в радианах) Гиперболический тангенс числа, выраженный в радианах Котангенс Арксинус (число должно быть в диапазоне от -1 до 1, результат от –π/2 до π/2) ASINH Гиперболический (число) арксинус числа, выраженный в радианах ACOS Арккосинус (число) (число должно быть в диапазоне от -1 до 1, результат от 0 до π) ACOSH Гиперболический (число) арккосинус числа, выраженный в радианах ATAN Арктангенс (число) (возвращает результат в диапазоне от –π/2 до π/2) COS (число) COS (число) COSH (число) Нет TAN (число) TAN (число) TANH (число) Нет Нет COT (число) ASIN (число) ASIN (число) Нет Нет ACOS (число) ACOS (число) Нет Нет ATAN (число) ATAN (число) 22 ATAN2 (число1 , число2) ATAN H (число) Нет Нет Арктангенс в градусах, вычисляемый как арктангенс результата деления одного тангенса на другой – ATAN(число1/числ о2). Возвращает результат в диапазоне (–π; π] Гиперболический арктангенс числа, выраженный в радианах ATAN2 (число1, число2) ATN2(число 1, число2) Нет Нет Окончание табл. 3.4 DEGREES Нет (число) Возвращает для значения угла в радианах соответствующее значение в градусах Для введенного RADIANS Нет числового (число) выражения в градусах возвращает значение в радианах Логические функции Логическое 'И' на Нет (число AND всех аргументах [,число...]) BIN_A ND (число [,число. ..]) BIN_N Логическое 'НЕ' OT аргумента (число) Нет NOT (число) 23 BIN_O Логическое 'ИЛИ' Нет (число OR R на всех [,число...]) (число аргументах [,число >…]) BIN_X Исключающее Нет (число XOR OR 'ИЛИ' на всех [,число...]) (число аргументах [,число. ..]) BIN_S Двоичный сдвиг Нет число << HL влево число (число, число) BIN_S Двоичный сдвиг Нет число >> HR вправо число (число, число) Пример запроса в Firebird по использованию числовых функций: SELECT POWER(COS(PI()),2) + POWER(SIN(PI()),2) FROM RDB$DATABASE; Функции даты и времени. Как уже отмечалось, эти функции выполняют различные действия над входными значениями времени и даты и возвращают строковое, числовое значения или значение в формате даты и времени. Функция EXTRACT используется для извлечения различных частей даты и времени. В Firebird функция EXTRACT используется для выделения года(1–9999), месяца(1–12), дня(1–31), дня года(0[1 января]–365), дня недели(0[воскресенье]–6), часа(0–23), минуты(0–59), секунды(0–59.9999), а также недели в году(1–52). Синтаксис этой функции EXTRACT( { YEAR | MONTH | DAY | YEARDAY | WEEKDAY | HOUR | MINUTE | SECOND | WEEK } FROM [DATE] <значение> ), где <значение> – любое выражение, возвращающее результат типа DATE, TIME или TIMESTAMP. Если выражение представляет собой константу, то после FROM указывается слово DATE, в остальных случаях <значение> указывается непосредственно после FROM. Выделяемая часть должна присутствовать в <значение>. Пусть, например, требуется для каждой ремонтной заявки, год поступления которой отличается от 2013, указать ее номер, день, месяц и год поступления (рис. 3.32). Для этого можно использовать запрос SELECT RequestCD, EXTRACT(DAY FROM IncomingDate) AS "IncomingDay", EXTRACT (MONTH FROM IncomingDate) AS "IncomingMonth", EXTRACT (YEAR FROM IncomingDate) AS "IncomingYear" FROM Request 24 WHERE EXTRACT (YEAR FROM IncomingDate) IS DISTINCT FROM 2013; REQUESTCD 1 2 3 5 6 7 9 10 12 13 15 16 17 18 19 20 21 22 23 IncomingDay 17 7 28 31 16 20 6 1 8 4 20 28 15 28 17 11 13 18 7 IncomingMonth 12 8 2 12 6 10 11 4 8 9 9 12 8 12 12 10 9 5 5 IncomingYear 2011 2011 2012 2011 2011 2012 2011 2011 2011 2010 2010 2011 2011 2012 2011 2011 2011 2011 2011 Рис. 3.32. Результат работы функции EXTRACT В Oracle функция EXTRACT используется для выделения года(1–9999), месяца(1–12), дня(1–31), часа(0–23), минуты(0–59), секунды(0–59.99…), часа, минуты, названия или сокращенного названия часового пояса и имеет формат EXTRACT( { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | TIMEZONE_HOUR | TIMEZONE_ MINUTE | TIMEZONE_REGION | TIMEZONE_ABBR } FROM <значение> ). В MS SQL Server вместо функции EXTRACT используется ряд других функций для получения компонентов даты и времени: DATEPART, DATENAME, DAY, MONTH, YEAR. Функция DATEPART является синонимом стандартной функции EXTRACT и имеет формат DATEPART (часть_даты, значение). Платформа MS SQL Server поддерживает части даты, перечисленные в табл. 3.5 [37]. В качестве результата функция возвращает целое число. Помимо DATEPART, могут использоваться функции DAY(значение), MONTH(значение) и YEAR(значение), которые возвращают целое число, представляющее день, месяц или год указанной даты. Для получения строкового представления указанной части даты используется функция DATENAME, имеющая формат DATENAME (часть_даты, значение). 25 Также MS SQL Server поддерживает функции для получения значения даты и времени из их компонентов. Среди них функция DATEFROMPARTS, которая возвращает значение типа date, соответствующее указанному числу, месяцу и году, и функция DATETIMEFROMPARTS, которая возвращает значение типа datetime, соответствующее указанной дате и времени. Функции имеют формат DATEFROMPARTS (год, месяц, день); DATETIMEFROMPARTS (год, месяц, день, час, минута, секунда, миллисекунда). Могут использоваться и другие функции MS SQL Server, возвращающие значения других типов дата/время из компонентов [37]. Таблица 3.5. Компоненты даты/времени MS SQL Server Часть даты Сокра Описание щения YY, Год YEAR YYYY QUARTER QQ, Q Квартал MONTH MM, M Месяц DAYOFYEAR DY, Y День года DAY DD, D День WK, Неделя WEEK WW WEEKDAY DW День недели HOUR HH Час MINUTE MI, N Минута SECOND SS, S Секунда MILLISECOND MS Миллисекунда MICROSECOND MCS Микросекунда NANOSECOND NS Наносекунда Количество TZOFFSET TZ минут Функция ISDATE в MS SQL Server определяет, является ли входное выражение допустимым значением даты или времени и возвращает значение 0 или 1 в зависимости от результатов проверки. Функция имеет формат ISDATE (выражение). Для получения значений текущей даты и системного времени используются константы времени и контекстные переменные (см. разд. 2.8). Например, вывести данные таблицы Services, текущие серверные дату и время (29.10.2015, 18:21) в Firebird можно с помощью запроса SELECT S.*, CURRENT_TIMESTAMP FROM Services S; Результат выполнения запроса представлен на рис. 3.33. 26 SERVICECD 1 2 3 4 SERVICENM Газоснабжение Электроснабжение Теплоснабжение Водоснабжение CURRENT_TIMESTAMP 29.10.2015 18:21 29.10.2015 18:21 29.10.2015 18:21 29.10.2015 18:21 Рис. 3.33. Результат работы функции CURRENT_TIMESTAMP Функция DATEADD возвращает значение типа дата, время или дата/время, увеличенное или уменьшенное (если количество отрицательное) по сравнению с исходным значением на заданное количество лет, месяцев, дней, часов, минут, секунд или миллисекунд. В Firebird функция имеет следующий формат: DATEADD ( количество <временной_отрезок> TO <значение> ) или DATEADD (<временной_отрезок>, количество, <значение> ), где количество – количество прибавляемых или вычитаемых единиц; <временной_отрезок> ::= { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | MILLISECOND }; <значение> – значение типа дата, время или дата/время, которое увеличивается или уменьшается. Следует отметить:  что YEAR, MONTH и DAY в качестве временного отрезка не могут использоваться со значениями типа время (например, тип TIME);  HOUR, MINUTE, SECOND и MILLISECOND в качестве временного отрезка не могут использоваться со значениями типа дата (например, тип DATE);  все значения временного отрезка могут быть использованы для типов дата/время (TIMESTAMP). Например, требуется вывести даты регистрации ремонтных заявок с кодом неисправности, равным 1, и даты через 14 дней после их регистрации (рис. 3.34). Запрос будет выглядеть следующим образом: SELECT IncomingDate, DATEADD (14 DAY TO IncomingDate) AS "Exec_Limit" FROM Request WHERE FailureCD = 1; INCOMINGDATE 17.12.2011 07.08.2011 31.12.2011 06.11.2011 Exec_Limit 31.12.2011 21.08.2011 14.01.2012 20.11.2011 Рис. 3.34. Результат работы функции DATEADD в Firebird MS SQL Server поддерживает функцию DATEADD в формате DATEADD (<временной_отрезок>, количество, <значение> ). 27 Таким образом, предыдущий запрос должен быть записан в MS SQL Server как SELECT IncomingDate,DATEADD (DAY, 14,IncomingDate) AS "Exec_Limit" FROM Request WHERE FailureCD = 1; Результат выполнения запроса (рис. 3.35) будет отличаться от результата на рис. 3.34 форматом вывода даты (дата выводится в формате UTC). INCOMINGDATE Exec_Limit 2011-12-17 2011-12-31 2011-08-07 2011-08-21 2011-12-31 2012-01-14 2011-11-06 2011-11-20 Рис. 3.35. Результат работы функции DATEADD в MS SQL Также в MS SQL Server может использоваться функция EOMONTH для получения последнего дня месяца, содержащего заданную дату, с необязательным смещением [37]. Функция имеет формат EOMONTH ((<дата> [,<количество_месяцев> ] ), где <дата> – выражение даты, для которой необходимо возвратить последний день месяца; <количество_месяцев> – необязательное целочисленное выражение, задающее количество месяцев, добавляемых к дате. Если <количество_месяцев> указано, то EOMONTH добавляет указанное число месяцев к значению даты и возвращает последний день месяца, соответствующего полученной дате. СУБД Oracle не поддерживает функцию DATEADD, вместо нее для получения даты со сдвигом от заданной используется ряд других функций. Функция ADD_MONTHS возвращает дату, полученную в результате прибавления к исходной дате заданного числа месяцев. Формат функции: ADD_MONTHS(<дата>, <количество_месяцев>). Количество месяцев может быть отрицательным – в этом случае указанное <количество_месяцев> вычитается из заданной даты. Функция LAST_DAY возвращает последний день месяца на основе значения даты, имеет формат LAST_DAY((<дата>). Функция NEXT_DAY возвращает дату первого указанного дня недели, следующего за заданной датой. Имеет формат NEXT_DAY(<дата>, <день_недели>), где <дата> используется для поиска следующего дня недели; <день_недели> – день недели, дата которого ищется (понедельник, вторник, среда, четверг, пятница, суббота, воскресенье). Например, если необходимо получить дату первой среды после 1 декабря 2014 года (рис. 3.36), то в Oracle можно использовать запрос SELECT NEXT_DAY('01.12.2014', 'Среда') AS "Result" FROM DUAL; 28 Result 03.12.2014 Рис. 3.36. Результат работы функции NEXT_DAY Функции TRUNC и ROUND, описанные выше в качестве числовых функций, в Oracle могут использоваться для работы со значениями дата/время. Функция TRUNС производит усечение указанной даты в соответствии с маской. Функция имеет формат TRUNС(<дата>,[<маска>]). Если маска не указана, то усечение производится до даты (время отбрасывается). Например, вывести текущую дату в исходном и усеченном виде (рис. 3.37) можно с помощью запроса SELECT SYSDATE d1, TRUNC(SYSDATE) d2 FROM DUAL; D1 D2 04.12.2014 19:45 04.12.2014 0:00 Рис. 3.37. Результат работы функции TRUNC без маски Функция ROUND аналогична TRUNC, но вместо усечения она производит округление. В табл. 3.6 приведён перечень форматных масок, которые можно использовать в функциях TRUNC и ROUND. Таблица 3.6. Форматные маски для функций ROUND и TRUNC Маска Назначение СС Первый день столетия YEAR, или YYYY, или YY, или Первый день года Y Q Первый день квартала MONTH, или MON, или MM Первый день месяца WW Тот же день недели, что и первый день текущего года W Тот же день недели, что и первый день текущего месяца DDD или DD День (маска по умолчанию) DAY, или DY, или D Первый день недели HH, или HH12, или HH24 Час MI Минута Рассмотрим типовые примеры – усечение и округление даты до часов, дней, месяца и года. Запрос на вывод текущей даты, усеченной до различных форматов (рис. 3.38): 29 SELECT SYSDATE d1, TRUNC(SYSDATE, 'HH24') d2, TRUNC(SYSDATE, 'DD') d3, TRUNC(SYSDATE, 'MM') d4, TRUNC(SYSDATE, 'YYYY') d5 FROM DUAL; D1 26.09.2006 16:49:21 D2 D3 D4 D5 26.09.2006 26.09.2006 01.09.2006 01.01.2006 16:00:00 Рис. 3.38. Результат работы функции TRUNC Вывести текущую дату округленной до различных форматов (рис. 3.39) можно с помощью запроса SELECT SYSDATE d1, ROUND(SYSDATE, 'HH24') d2, ROUND(SYSDATE) d3, ROUND(SYSDATE, 'DD') d4, ROUND(SYSDATE, 'MM') d5 FROM DUAL; D1 26.09.2006 16:50:50 D2 D3 D4 D5 26.09.2006 27.09.2006 27.09.2006 01.10.2006 17:00:00 Рис. 3.39. Результат работы функции ROUND Для определения величины временного промежутка от первого заданного значения до второго в выбранных единицах измерения времени может использоваться функция DATEDIFF. Функция DATEDIFF поддерживается в Firebird и в MS SQL Server. В Firebird функция возвращает значение типа BIGINT и имеет формат DATEDIFF ( <временной_отрезок> FROM <значение1> TO <значение2> ) или DATEDIFF ( <временной_отрезок>, <значение1>, <значение2> ). где <временной_отрезок> имеет тот же синтаксис, что и в функции DATEADD. Нужно отметить, что:  функция возвращает положительное число, если <значение2> превышает <значение1>, отрицательное – если <значение1> превышает <значение2>, и ноль – если значения равны;  если результат вычисления дробный, то выводится округленное значение;  сравнение значения типа DATE со значением типа TIME недопустимо;  как и для функции DATEADD, определенные временные отрезки могут использоваться только с соответствующим им типом. REQUESTCD Interval Например, требуется для 5 заявок, поданных абонентом 2 3 с лицевым счетом '115705', 15 NULL вывести количество дней, 16 прошедших от даты 17 22 регистрации заявки до 18 7 момента ее выполнения (рис. Рис. 3.40. Результат 3.40). Для этого можно работы использовать запрос 30 функции DATEDIFF SELECT RequestCD, DATEDIFF (DAY FROM IncomingDate TO ExecutionDate) AS "Interval" FROM Request WHERE AccountCD = '115705'; В MS SQL Server функция поддерживается в формате DATEDIFF ( <временной_отрезок>, <значение1>, <значение2> ). Таким образом, предыдущий запрос в MS SQL Server должен быть записан так: SELECT RequestCD, DATEDIFF(DAY,IncomingDate,ExecutionDate) AS Interval FROM Request WHERE AccountCD = '115705'; В Oracle функция DATEDIFF не используется. Для определения величины временного промежутка от первого заданного значения до второго в месяцах в Oracle может использоваться функция MONTHS_BETWEEN. Данная функция имеет формат MONTHS_BETWEEN(<дата_окончания>, <дата_начала>). Например, предыдущий запрос, преобразованный для вычисления разницы в месяцах (рис. 3.41), в Oracle можно записать в виде SELECT RequestCD, MONTHS_BETWEEN(EXECUTIONDATE, IncomingDate) AS Months FROM Request WHERE AccountCD = '115705'; REQUESTCD MONTHS 2 0,1612903225806451612903225806451612903226 15 0,0967741935483870967741935483870967741935 16 (null) 17 0,7096774193548387096774193548387096774194 18 0,2258064516129032258064516129032258064516 Рис. 3.41. Результат работы функции MONTHS_BETWEEN Функции преобразования типа. В тех случаях, когда СУБД не может выполнить неявное преобразование типов, требуется выполнять явное преобразование. В Firebird явное преобразование выполняется с помощью функции CAST. Эта функция производит преобразование значения выражения, заданного первым аргументом, в тип, заданный вторым аргументом. Синтаксис функции: CAST (<выражение> AS <тип данных>). В качестве типа данных нельзя указывать домены. В большинстве случаев использование функции CAST не требуется, так как Firebird производит неявное преобразование типов данных. Например, сравнение столбца типа DATE с датой '12/31/2013' приведет к неявному преобразованию строкового литерала '12/31/2013' в тип данных DATE, и следующий запрос будет корректным: SELECT * FROM Request WHERE IncomingDate < '12/31/2013'; 31 Можно использовать функцию CAST для сравнения столбцов с различными типами данных из одной и той же таблицы или из различных таблиц. С помощью CAST можно выполнять преобразование из одного типа дата/время в другой. В табл. 3.7 представлены правила преобразования [29]. Таблица 3.7. Преобразования между типами дата/время Исходн В тип В тип В тип ый тип TIMESTAMP DATE TIME TIMEST Недоступно Да, Да, AMP преобразуе преобразует т дату, время, игнорируя игнорируя время дату DATE Да, время Недоступн Нет устанавливается о в значение полуночи TIME Да, дате Нет Недоступно присваивается значение CURRENT_DATE DATE+T Да Нет Нет IME При использовании констант даты 'NOW', 'TODAY', 'TOMORROW' и 'YESTERDAY' в SQL-запросах необходимо явно выполнить их преобразование к нужному типу данных, иначе они будут рассматриваться как строковые константы. Примерами использования константы 'YESTERDAY' могут служить запросы: SELECT * FROM PaySumma WHERE PayDate < CAST('YESTERDAY' AS DATE);, SELECT * FROM PaySumma WHERE PayDate < DATE 'YESTERDAY';, возвращающие всю информацию об оплатах, произведенных ранее вчерашней даты. Можно также преобразовывать правильно сформированную строку в тип «дата-время». Например, значение с типом даты из трех значений дня, месяца и года можно получить следующим образом: CAST(DAY || '. ' || MONTH || '. ' || YEAR AS DATE), где DAY, MONTH и YEAR могут представлять собой константы или столбцы таблицы, в которых содержится значение соответственно дня, месяца и года. Например, если требуется вывести различные значения месяца и года начислений за услугу с кодом 2, отнесенные на первое число соответствующего месяца (рис. 3.42), то запрос может выглядеть так: SELECT DISTINCT NachislMonth, NachislYear, 32 CAST('1.' || NachislMonth || '.' || NachislYear AS DATE) AS "FirstDay" FROM NachislSumma WHERE ServiceCD = 2; NACHISLMONTH 1 1 4 5 6 8 9 9 10 10 11 12 12 NACHISLYEAR 2010 2013 2013 2011 2011 2011 2010 2011 2011 2012 2011 2010 2011 FirstDay 01.01.2010 01.01.2013 01.04.2013 01.05.2011 01.06.2011 01.08.2011 01.09.2010 01.09.2011 01.10.2011 01.10.2012 01.11.2011 01.12.2010 01.12.2011 Рис. 3.42. Результат работы функции CAST Кроме этого, можно преобразовывать числовые типы в строку и наоборот. Например, чтобы при выводе увеличить номер лицевого счета всех абонентов на 2, нужно использовать запрос SELECT (CAST (AccountCD AS INTEGER)+2) AS New_Acc, Fio FROM Abonent; Если нужно вывести значения начислений абоненту с номером лицевого счета '115705' округленными до целого значения (рис. 3.43), то для этого можно использовать запрос: SELECT NachislFactCD, NachislSum, CAST(NachislSum AS INTEGER) AS "RoundSum" FROM NachislSumma WHERE AccountCD='115705'; NACHISLFACTCD 4 5 11 12 25 31 37 49 71 NACHISLSUM 40,00 250,00 250,00 58,70 37,15 37,80 37,15 37,15 553,85 RoundSum 40 250 250 59 37 38 37 37 554 Рис. 3.43. Результат округления числа до целого значения с помощью функции CAST 33 Для получения значения, округленного до целого, можно также использовать описанную выше функцию ROUND с указанием точности, равной нулю. В таком случае значения будут выведены с нулями после запятой. СУБД MS SQL Server и Oracle также поддерживают функцию CAST для выполнения преобразования типов. Помимо функции CAST, MS SQL Server для преобразования типов данных поддерживает функцию CONVERT в формате CONVERT (<тип данных> [ (<длина> ) ] , <выражение> [ , <стиль> ] ), где <длина> – длина целевого типа данных; <стиль> – целочисленное выражение, определяющее, как функция CONVERT преобразует <выражение>. Параметр <стиль> для каждого типа данных MS SQL Server может иметь определенный набор значений [37]. Если <стиль> имеет значение NULL, возвращается NULL. СУБД Oracle предлагает больше тридцати однострочных функций, позволяющих переводить значение из одного типа данных в другой. Одной из самых популярных функций преобразований является TO_CHAR, которая превращает дату или время в строку символов. Не менее популярными функциями являются TO_DATE и TO_NUMBER. Кроме того, существуют функции преобразования из двоичного формата в формат с плавающей запятой, из многобайтовых в однобайтовые символы и пр. Рассмотрим три популярные функции преобразования: TO_CHAR, TO_DATE и TO_NUMBER. Функция TO_CHAR применяется для преобразования даты или времени в строку символов и имеет следующий синтаксис: TO_CHAR(<выражение>[,<маска>]). Параметр <выражение> - это дата/время или числовое значение, столбец или выражение, за которым после необязательного параметра следует <маска>. Параметр <маска>, формально называемый форматной маской, задаёт точный формат выходной строки символов. Например, чтобы преобразовать столбец PayDate таблицы PaySumma в выходную строку, имеющую другой формат, необходимо следующим образом использовать функцию TO_CHAR в запросе: SELECT TO_CHAR(PayDate,'Month DD, YYYY') "PayDate" FROM PaySumma; В результате получим даты оплаты услуг вида «January 08, 2012» или «May 06, 2013». Можно пропустить форматную маску, тогда Oracle будет использовать формат, принятый по умолчанию, DD-MON-YYYY или DDMON-YY (например, 03-SEP-2011). Функция TO_CHAR часто используется для форматирования числовых результатов в форму, более удобную для восприятия. Например, с помощью приведённой ниже функции TO_CHAR можно преобразовать и отобразить на экране значения столбца, расположив перед ним символ доллара, использовав для отделения миллионов и тысяч запятую и округляя значения с точностью до двух знаков после десятичной точки. 34 SELECT TO_CHAR(1593480.829,'$9,999,999.99') "PayDate" FROM DUAL; Запрос выдаст строку «$1,593,480.83». Указанная модель формата, '$9,999,999.99', означает, что перед значением ставится знак $, а каждый символ 9 означает один разряд. Точка указывает положение десятичного разделителя, а следующие за ней две девятки обозначают, что в результате необходимо указывать два знака после запятой (даже если это 00). Существует целый набор символов модели формата, которые можно использовать для форматирования дат или чисел. Некоторые из важнейших символов, которые можно использовать в различных комбинациях при задании формата, перечислены в табл. 3.8. Рассмотрим пример еще одного запроса, результат которого представлен на рис. 3.44: SELECT TO_CHAR(345.678,'99,999.99') AS "99,999.99", TO_CHAR(0.00678,'9.999EEEE') AS "9.999EEEE", TO_CHAR(5280,'99.99') AS "09.99", TO_CHAR(1256,'RN') AS "RN: 1,256", TO_CHAR(1234.5678,'009,999.00') AS "009,999.00" FROM DUAL; 99,999.99 9.999EEEE 99.99 RN: 009,999.00 1,256 345.68 6.780E-03 ###### MCCLVI 001,234.57 Рис. 3.44. Действие форматных масок функции TO_CHAR Поскольку в форматной маске первого столбца количества разрядов слева от точки больше количества разрядов значения, то в результате число выводится с отступом слева. Второй столбец демонстрирует вывод результата в экспоненциальной форме. В третьем столбце количество позиций форматной маски недостаточно для отображения числа, поэтому результат выводится в виде символов #. Чтобы число отображалось правильно, нужно расширить форматную маску до необходимого количества разрядов. Четвёртый столбец показывает вывод числа римскими цифрами. И в последнем столбце нули добавляются в начале числа. Таблица 3.8. Элементы, применяющиеся для задания формата чисел Элемен Пример Описание т 9 999 Возвращает значение с заданным количеством цифр. Если число положительное, оно начинается с пробела, если отрицательное – со знака «минус». Число девяток соответствует максимальному количеству цифр, отображаемых на экране 35 Возвращает запятую в заданной позиции. Запятая не может быть первым элементом или появляться после десятичного разделителя . (точка) 99.99 Возвращает точку и помечает начало дробной части числа. Преобразуемое выражение округляется с точностью до разряда, заданного форматной маской 0999 Число начинается с нулей 9990 Число завершается нулями $ $999,999 Число начинается со знака доллара B B999 Если целая часть числа равна нулю, вместо неё подставляются пробелы MI 9999MI Если значение отрицательное, знак «минус» ставится в конце. Если число положительное, в конце ставится пробел RN RN Возвращает число прописными римскими цифрами rn Возвращает число строчными римскими цифрами S S9999 Для отрицательных значений в начале числа ставится знак «минус», для положительных – знак «плюс» или Для отрицательных значений в 9999S конце числа ставится знак «минус», для положительных – знак «плюс» EEEE 9,99EEE Возвращает значение в E экспоненциальной форме записи (например, 1.78Е+03) , 9,999 (запятая ) Функция TO_DATE преобразует строку в дату/время, имеет синтаксис: TO_DATE(<выражение>[,<маска>] [, <кодировка>])), где <выражение> – это строка, которую необходимо преобразовать в дату, а <маска> – необязательная модель формата, указывающая Oracle, как интерпретировать строку даты, <кодировка> – необязательный параметр, отвечающий за настройки языка для преобразования. Если формат не указывается, строка даты должна иметь один из принятых по умолчанию 36 форматов – DD-MON-YY или DD-MON-YYYY (в одинарных кавычках). Символьные названия месяцев должны быть записаны в соответствии с языковыми настройками для БД Oracle либо должна быть указана <кодировка>, используемая для преобразования. Формат дат по умолчанию определяется параметрами NLS_DATE_FORMAT (отвечает за сам формат как таковой) и NLS_DATE_LANGUAGE (отвечает за язык, который будет использован при написании названий дней, месяцев и т.д.) и может быть задан на уровне БД, уровне экземпляра или уровне сессии. Ниже приведено несколько примеров функции TO_DATE (языковые настройки БД по умолчанию – русский язык): TO_DATE('Январь 10, 2013', 'Month DD,YYYY'); TO_DATE('January 10, 2013', 'Month DD,YYYY' ,'NLS_DATE_LANGUAGE = American'); TO_DATE('10/17/2014 10:27:48', 'MM/DD/YYYY HH24:MI:SS'); TO_DATE('7.14.12', 'MM.DD.YY'); TO_DATE('2006/9/14', 'YYYY/MM/DD'); TO_DATE('10-ФЕВ-2010'). В первом примере модель формата указывает роль каждого элемента строки даты: дата начинается с полного названия месяца, затем идёт двухзначное представление дня месяца (DD), запятая и четырёхзначное представление года (YYYY). Другие примеры формата точно так же соответствуют форме строк даты, находящихся перед ними. Исключением является только пятый пример – он имеет форму, принятую по умолчанию, поэтому Oracle интерпретирует её правильно без помощи строки формата. Наиболее важные элементы модели формата даты, их значения и примеры использования приведены в табл. 3.9. Для преобразования строки в тип данных даты/времени в Oracle можно, например, использовать запрос SELECT TO_DATE('Январь 10, 2011','Month DD, YYYY') AS "Date-1", TO_DATE('10/07/2009 14:23:39','MM/DD/YYYY HH24:MI:SS') AS "Date-2" FROM DUAL;, результат которого представлен на рис. 3.45. Date-1 Date-2 10.01.2011 0:00:00 07.10.2009 14:23:39 Рис. 3.45. Пример работы функции TO_DATE Стоит обратить внимание на то, что результат отображается в формате Oracle, установленном по умолчанию. Функция TO_NUMBER используется для преобразования в число и имеет следующий формат: TO_NUMBER(<выражение>[,<маска>])). Строка формата модели (<маска>) может содержать те же элементы, что перечислены в табл. 3.8. Далее приведен запрос, который преобразует значения столбца AccountCD в число, добавляя к нему 10 (рис. 3.46): SELECT AccountCD, TO_NUMBER(AccountCD)+10 AS "AccountCD+10" 37 FROM NachislSumma WHERE ServiceCD = 4; ACCOUNTCD 015527 015527 080270 080270 080270 115705 126112 136159 136159 136169 443069 443069 443690 443690 AccountCD+10 15537 15537 80280 80280 80280 115715 126122 136169 136169 136179 443079 443079 443700 443700 Рис. 3.46. Результат работы функции TO_NUMBER Таблица 3.9. Элементы моделей формата, относящихся к дате и времени Понятие Параметр Описание Пример Столетие CC Двухзначное представление 20, 21 века Квартал Q Однозначное представление 1, 2, 3 или 4 квартала года Год YYYY, YYY, Год, представленный 2015, 006, 06, 6 YY, Y, RR четырьмя, тремя, двумя или одной цифрой. RR – округление до ближайшего года Месяц MONTH, Месяц, представленный JANUARY, Month, MON, полным или сокращённым January, JAN или Mon именем. Использование Jan прописных/строчных букв – как в шаблоне MM Двухзначное представление 01, 02, …, 12 месяца Неделя WW, W Двухзначное представление 01-52, 1-5 недели года, однозначное представление недели месяца День DDD, DD, D Трехзначное представления 38 SP дня года, двухзначное представление дня месяца, однозначное представление дня недели День недели: полное название, сокращенное название, прописными буквами, прописная и строчные буквы соответственно Двухзначное представление часа в 24- или 12-часовом формате Двухзначное представление минуты Двухзначное представление секунды. Диапазон: 0-59 Символы, используемые для разделения значения даты и времени (дефис, косая черта, точка с запятой, запятая, двоеточие, точка) Время до (AM, A.M.) или после полудня (PM, P.M.) Год до нашей эры (BC, B.C.) или нашей эры (AD, A.D.) Задает суффикс для порядковых чисел Число записывается словами TZR Часовой пояс DAY, Day, DY, Dy Час HH24, HH Минута MI Секунда SS Разделители - / ; , : . Суффиксы времени AM, A.M., PM, P.M. AD, BC, A.D., B.C. TH SUNDAY, Sunday, SUN, Sun 23, 11 Диапазон: 0-59 DD-MONYYYY; HH:MM:SS; YYYY/MM/DD 12:45 P.M. 1452 B.C. 1ST, 2ND, 3RD или 15TH DDSP дает FIFTEEN (если день равен 15) PST, EST 3.2.3.3. Агрегатные функции Для подведения итогов по данным, содержащимся в БД, в языке SQL предусмотрены агрегатные (статистические) функции. Агрегатная функция берет в качестве аргумента какой-либо столбец (для множества строк), а возвращает одно значение, определяемое типом функции. Основные агрегатные функции, поддерживаемые всеми рассматриваемыми СУБД:  AVG – среднее значение в столбце;  SUM – сумма значений в столбце;  MAX – наибольшее значение в столбце;  MIN – наименьшее значение в столбце;  COUNT – количество значений в столбце. 39 Аргументами агрегатных функций могут быть как столбцы таблицы, так и результаты выражений над ними. При этом выражение может быть сколь угодно сложным. Агрегатные функции могут использоваться в секции SELECT, а также в секции HAVING. Вложенность агрегатных функций не допускается, однако из этих функций можно составлять любые выражения. Для функций SUM и AVG столбец должен содержать числовые значения. Специальная функция COUNT (*) служит для подсчета всех без исключения строк в таблице (включая дубликаты). Результатом функции COUNT не может быть NULL. Она может вернуть только натуральное число (положительное целое) или ноль. Все другие агрегатные функции могут дать на выходе NULL, если аргумент не содержит ни одной строки или содержит строки, включающие только NULL. Аргументу всех функций, кроме COUNT (*), может предшествовать ключевое слово DISTINCT (различный), указывающее, что избыточные дублирующие значения должны быть исключены перед тем, как будет применяться функция. Если не используется секция GROUP BY, но в секции SELECT используется какая-либо агрегатная функция, то в качестве возвращаемых элементов нельзя указывать по отдельности столбцы таблиц (можно лишь в качестве аргументов агрегатных функций). Вычисление среднего значения. Для вычисления среднего всех значений, содержащихся в столбце, используется агрегатная функция AVG. Данные, содержащиеся в столбце, должны иметь числовой тип. Функция AVG подсчитывает сумму известных значений и делит ее на количество этих значений, а не на общее количество значений, среди которых могут быть NULL. В общем случае возвращаемый функцией результат может иметь тип, не совпадающий с типом столбца. Синтаксис использования функции AVG({[[ALL] | DISTINCT] столбец | [DISTINCT] <выражение>}). При указании аргумента ALL происходит вычисление по всем известным значениям множества элементов. Если указан аргумент DISTINCT, то перед вычислением среднего значения из рассмотрения исключаются дублирующиеся значения. Если число строк, обрабатываемых агрегатной функцией AVG, равно нулю или значения всех элементов не определены, то функция возвращает NULL. Выражение представляет собой скалярное численное выражение языка SQL. Например, чтобы вычислить среднее значение оплат всех абонентов, необходимо выполнить запрос: AVG SELECT AVG(Paysum) FROM 161,15 Paysumma; Результат выполнения Рис. 3.47. запроса представлен на рис. Результат работы 3.47. функции AVG Аргументом агрегатной функции может быть как простое имя столбца, как в предыдущем примере, так и выражение, как, например, в следующем запросе: 40 SELECT AVG(NachislSum+2) FROM NachislSumma; При вычислении среднего к каждому суммируемому значению NachislSum добавляется число 2, а затем полученная сумма делится на количество значений. В результате выполнения данного запроса будет возвращено число 168,02. Вычисление суммы значений в столбце. Для вычисления суммы значений, содержащихся в столбце, используется агрегатная функция SUM. При этом столбец должен иметь числовой тип данных. Результат, возвращаемый этой функцией, имеет тот же тип данных, что и столбец, но количество значащих цифр может быть больше, чем количество значащих цифр отдельных значений в столбце. Использование этой функции аналогично использованию функции AVG. Синтаксис использования функции SUM: SUM({[[ALL] | DISTINCT] столбец | [DISTINCT] <выражение>}). SUM Например, для нахождения 12949,73 суммы всех значений начислений (рис. 3.48) можно использовать Рис. 3.48. запрос: Результат SELECT SUM(NachislSum) FROM работы NachislSumma; функции SUM Вычислить среднее значение оплат и сумму всех оплат за услугу с кодом 1 можно так: SELECT AVG(PaySum), SUM(PaySum) FROM PaySumma WHERE ServiceCD=1; Вычисление экстремумов. Для нахождения наименьшего или наибольшего значения в столбце используются агрегатные функции – соответственно MIN или MAX. При этом столбец может содержать числовые и строковые значения либо значения даты/времени. Синтаксис использования агрегатных функций по нахождению максимального и минимального значений: MAX({[[ALL] DISTINCT] столбец | [DISTINCT] <выражение>}), MIN({[[ALL] | DISTINCT] столбец | [DISTINCT] <выражение>}). Результат, возвращаемый этими функциями, имеет такой же тип данных, что и сам столбец. В случае применения функций MIN и MAX к числовым данным числа сравниваются по арифметическим правилам. Например, чтобы найти в таблице PaySumma максимальное и минимальное значения оплат (рис. 3.49), можно выполнить запрос: SELECT MAX(PaySum), MIN(PaySum) FROM PaySumma; Сравнение дат MAX MIN происходит 611,30 8,30 последовательно: более Рис. 3.49. Результат ранние значения дат считаются меньшими, чем работы 41 более поздние. функций MAX и MIN Сравнение интервалов времени выполняется на основании их продолжительности: более короткие интервалы времени меньше, чем более длинные. Вычисление количества значений в столбце. Количество значений в столбце подсчитывает функция COUNT. При этом тип данных столбца может быть любым. Синтаксис использования этой агрегатной функции такой: COUNT({ * | [[ALL] | DISTINCT] столбец | [DISTINCT] <выражение>}). Символ звездочки в качестве аргумента функции используется для подсчета количества строк в заданной таблице, включая признак NULL. Если в качестве аргумента выступает имя столбца, то состояния NULL в нем не рассматриваются. При использовании выражения (в том числе константы) в качестве аргумента функция оценивает <выражение> для каждой строки в группе и возвращает количество значений (в случае указания DISTINCT – уникальных), не равных NULL. Например, чтобы подсчитать общее количество абонентов, можно использовать запрос: SELECT COUNT(*) FROM Abonent;, а для подсчета числа абонентов с указанным номером телефона такой: SELECT COUNT(Phone) FROM Abonent; COUNT Следующий запрос позволяет подсчитать число 10 абонентов, которые подавали Рис. 3.50. заявки на ремонт газового Результат оборудования (рис. 3.50): работы функции SELECT COUNT(DISTINCT COUNT AccountCD) FROM Request; Таким образом, только 10 разных абонентов из двенадцати подавали заявки на ремонт оборудования, хотя всего в таблице ремонтных заявок содержится 21 строка (некоторые абоненты подавали несколько заявок). 3.2.3.4. Функции для списка выражений В СУБД могут поддерживаться функции для списка выражений. Такие функции, хотя и обрабатывают набор значений, но не являются агрегатными. В Firebird функции для списка выражений представлены функциями MAXVALUE, MINVALUE и LIST. Функции MAXVALUE и MINVALUE возвращают соответственно максимальное и минимальное значения из списка выражений своих аргументов. Имеют формат: MAXVALUE (<выражение1> [,<выражение2> ...] ), MINVALUE (<выражение1> [,<выражение2> ...] ) . Например, поставить в соответствие ремонтным заявкам, принятым исполнителем с кодом 1, дату их выполнения или 1 января 2012 г., если 42 соответствующая заявка была выполнена раньше этой даты, можно запросом: SELECT RequestCD, MAXVALUE (ExecutionDate, CAST ('01.01.2012' AS DATE)) FROM Request WHERE ExecutorCD = 1; Результат выполнения REQUESTCD MAXVALUE запроса представлен на 1 01.01.2012 рис. 3.51. 3 08.03.2012 6 01.01.2012 11 12.01.2013 17 01.01.2012 21 01.01.2012 22 01.01.2012 Рис. 3.51. Результат работы функции MAXVALUE Из результата предыдущего запроса следует, что заявкам с кодами 1, 6, 17, 21 и 22, имеющим дату выполнения ранее 01.01.2012 г., поставлена в соответствие дата 1 января 2012 г., а заявкам с кодами 3 и 11 поставлена в соответствие дата выполнения заявки. Следует учесть, что если одно и более значений выражений в списке содержат NULL, функции MAXVALUE и MINVALUE возвращают NULL. Если выполнить предыдущий запрос по исполнителю с кодом 4: SELECT RequestCD, MAXVALUE (ExecutionDate, CAST ('01.01.2012' AS DATE)) FROM Request WHERE ExecutorCD = 4; , то в возвращенной строке с RequestCD = 5 получим NULL в столбце MAXVALUE, так как у заявки с кодом 5 дата выполнения неизвестна. В СУБД Oracle вместо функций MAXVALUE и MINVALUE используются аналогичные функции GREATEST и LEAST [49]. Синтаксис функций: GREATEST (<выражение1> [,<выражение2> ...] ), LEAST (<выражение1> [,<выражение2> ...] ) . Примечания. 1. Если типы данных выражений разные, все выражения будут преобразованы в тип данных выражения <выражение1>. 2. Если сравнение основано на сравнении символов, один символ считается меньше, чем другой, если он имеет более низкое значение кода символов. 3. Если одно из выражений имеет значение NULL, в качестве значения функции будет возвращено NULL. Функция LIST может использоваться в Firebird для возврата строки, полученной в результате соединения известных значений (не NULL) из 43 списка, представленного набором значений аргумента функции (<выражение>). Функция LIST имеет формат: LIST ( [ {ALL | DISTINCT} ] <выражение> [ , <разделитель> ] ), где <разделитель> ::={строковая_константа | параметр | переменная | строковая функция}. Функция возвращает NULL, если все значения из списка имеют NULL. Примечание. Входные параметры и переменные могут выступать в качестве разделителей при использовании функции LIST в хранимых процедурах (хранимые процедуры будут подробно описаны далее). В качестве аргумента функции LIST могут быть заданы числовые значения и значения типа дата/время, которые в процессе работы функции преобразуются в строку (результирующее значение имеет тип BLOB). Нужно учитывать следующие синтаксические правила:  если ни ALL, ни DISTINCT не указаны, то по умолчанию применяется ALL;  если <разделитель> опущен, то для разделения соединяемых величин используется запятая. Например, для вывода в одну строку через запятую названий всех услуг (рис. 3.52) можно использовать следующий запрос: SELECT LIST (ServiceNM) FROM Services; LIST Газоснабжение,Электроснабжение,Теплоснабжение,Водоснабжение Рис. 3.52. Результат работы функции LIST 44
«Функции в SQL» 👇
Готовые курсовые работы и рефераты
Купить от 250 ₽
Решение задач от ИИ за 2 минуты
Решить задачу
Помощь с рефератом от нейросети
Написать ИИ

Тебе могут подойти лекции

Смотреть все 588 лекций
Все самое важное и интересное в Telegram

Все сервисы Справочника в твоем телефоне! Просто напиши Боту, что ты ищешь и он быстро найдет нужную статью, лекцию или пособие для тебя!

Перейти в Telegram Bot