|
|
Книги-online32 урока по Delphi 32 урока по Delphi Урок 30: Основы языка
SQL
Содержание урока 30: Состав языка SQL Реляционные операции. Команды языка манипулирования данными Команда SELECT Простейшие конструкции команды SELECT Список полей Все поля Все поля в произвольном порядке Блобы Вычисления Литералы Конкатенация Использование квалификатора AS Работа с датами Агрегатные функции Предложение FROM команды SELECT Ограничения на число выводимых строк Операции сравнения BETWEEN IN LIKE CONTAINING IS NULL Логические операторы Преобразование типов (CAST) Изменение порядка выводимых строк (ORDER BY) Упорядочивание с использованием имен столбцов Упорядочивание с использованием номеров столбцов Устранение дублирования (модификатор DISTINCT) Соединение (JOIN) Внутренние соединения Самосоединения Внешние соединения
Информационное пространство становится более унифицированным. Это привело к необходимости создания стандартного языка, который мог бы использоваться в большом количестве различных видов компьютерных сред. Стандартный язык позволит пользователям, знающим один набор команд, использовать их для создания, нахождения, изменения и передачи информации - независимо от того, работают ли они на персональном компьютере, сетевой рабочей станции, или на универсальной ЭВМ. В нашем все более и более взаимосвязанном компьютерном мире, пользователь снабженый таким языком, имеет огромное преимущество в использовании и обобщении информации из ряда источников с помощью большого количества способов. Элегантность и независимость от специфики компьютерных технологий, а также его поддержка лидерами промышленности в области технологии реляционных баз данных, сделало SQL (и, вероятно, в течение обозримого будущего оставит его) основным стандартным языком. По этой причине, любой, кто хочет работать с базами данных 90-х годов, должен знать SQL. Стандарт SQL определяется ANSI (Американским Национальным Институтом Стандартов) и в данное время также принимается ISO (Международной Организацией по Стандартизации). Однако, большинство коммерческих программ баз данных расширяют SQL без уведомления ANSI, добавляя различные особенности в этот язык, которые, как они считают, будут весьма полезны. Иногда они несколько нарушают стандарт языка, хотя хорошие идеи имеют тенденцию развиваться и вскоре становиться стандартами "рынка" сами по себе в силу полезности своих качеств. На данном уроке мы будем, в основном, следовать стандарту ANSI, но одновременно иногда будет показывать и некоторые наиболее общие отклонения от его стандарта. Точное описание особенностей языка приводится в документации на СУБД, которую Вы используете. SQL системы InterBase 4.0 соответствует стандарту ANSI-92 и частично стандарту ANSI-III. Поэтому, в язык SQL в качестве составных частей входят:
Язык манипулирования данными используется, как это следует из его названия, для манипулирования данными в таблицах баз данных. Он состоит из 4 основных команд: SELECT (выбрать) INSERT (вставить) UPDATE (обновить) DELETE (удалить).
CREATE TABLE (создать таблицу) CREATE VIEW (создать виртуальную таблицу) CREATE INDEX (создать индекс) CREATE TRIGGER (создать триггер) CREATE PROCEDURE (создать сохраненную процедуру) ALTER DATABASE (модифицировать базу данных) ALTER TABLE (модифицировать таблицу) ALTER VIEW (модифицировать виртуальную таблицу) ALTER INDEX (модифицировать индекс) ALTER TRIGGER (модифицировать триггер) ALTER PROCEDURE (модифицировать сохраненную процедуру) DROP DATABASE (удалить базу данных) DROP TABLE (удалить таблицу) DROP VIEW (удалить виртуальную таблицу) DROP INDEX (удалить индекс) DROP TRIGGER (удалить триггер) DROP PROCEDURE (удалить сохраненную
процедуру).
REVOKE (забрать права).
Мы не будем приводить точный синтаксис команд SQL, вместо этого мы рассмотрим их на многочисленных примерах, что намного более важно для понимания SQL, чем точный синтаксис, который можно посмотреть в документации на Вашу СУБД. Итак, начнем с рассмотрения команд языка манипулирования данными. На данном уроке предполагается, если не оговорено противное, что все команды языка SQL вводятся интерактивным способом. В качестве информационной основы для примеров мы будем использовать базу данных “Служащие предприятия” (employee.gdb), входящую в поставку Delphi и находящуюся (по умолчанию) в поддиректории \IBLOCAL\EXAMPLES.
???. 1: ????????? ???? ?????? EMPLOYEE На рис.1 приведена схема базы данных EMPLOYEE для Local InterBase, нарисованная с помощью CASE-средства S-Designor (см. доп. урок). На схеме показаны таблицы базы данных и взаимосвязи, а также обозначены первичные ключи и их связи с внешними ключами. Многие из примеров, особенно в конце урока, являются весьма сложными. Однако, не следует на этом основании делать вывод, что так сложен сам язык SQL. Дело, скорее, в том, что обычные (стандартные) операции настолько просты в SQL, что примеры таких операций оказываются довольно неинтересными и не иллюстрируют полной мощности этого языка. Но в целях системности мы пройдем по всем возможностям SQL: от самых простых - до чрезвычайно сложных. Начнем с базовых операций реляционных баз данных. Таковыми являются:
таблицы Country COUNTRY CURRENCY =============== ========== USA Dollar England Pound Canada CdnDlr Switzerland SFranc Japan Yen Italy Lira France FFranc Germany D-Mark Australia ADollar Hong Kong HKDollar Netherlands Guilder Belgium BFranc Austria Schilling Fiji FDollar
WHERE currency
= “Dollar” Получить
подмножество строк таблицы Country, удовлетворяющее условию Currency =
“Dollar”
=============== ========== USA Dollar
========== Dollar Pound CdnDlr SFranc Yen Lira FFranc D-Mark ADollar HKDollar Guilder BFranc Schilling FDollar
WHERE country
= “Japan” Найти денежную
========== Yen SELECT first_name, last_name FROM employee WHERE first_name
= "Roger" Получить
фамилии
=============== ==================== Roger De Souza Roger Reeves
FROM (из) специфицированной таблицы WHERE (где) некоторое специфицированное условие
является истинным
FROM employee, project WHERE emp_no
= team_leader Получить
список
============== ================= ==================== Ashok Ramanathan Video Database Pete Fisher DigiPizza Chris Papadopoulos AutoMap Bruce Young MapBrowser port Mary S. MacDonald Marketing
project 3
FROM employee WHERE job_country = "France" UNION SELECT contact_first, contact_last, country FROM customer WHERE country
= "France" Получить
список
=============== ================= =============== Jacques Glon France Michelle Roche France Для справки, приведем общую форму команды SELECT, учитывающую возможность соединения нескольких таблиц и объединения результатов: SELECT [DISTINCT] список_выбираемых_элементов (полей) FROM список_таблиц (или представлений) [WHERE предикат] [GROUP BY поле (или поля) [HAVING предикат]] [UNION другое_выражение_Select] [ORDER BY поле (или поля) или номер (номера)]; ???. 2: ????? ?????? ??????? SELECT Отметим, что под предикатом понимается некоторое специфицированное условие (отбора), значение которого имеет булевский тип. Квадратные скобки означают необязательность использования дополнительных конструкций команды. Точка с запятой является стандартным терминатором команды. Отметим, что в WISQL и в компоненте TQuery ставить конечный терминатор не обязательно. При этом там, где допустим один пробел между элементами, разрешено ставить любое количество пробелов и пустых строк - выполняя желаемое форматирование для большей наглядности. Гибкость и мощь языка SQL состоит в том, что он позволяет объединить все операции реляционной алгебры в одной конструкции, “вытаскивая” таким образом любую требуемую информацию, что очень часто и происходит на практике.
FROM phone_list
получить список
FIRST_NAME LAST_NAME PHONE_NO ============= ==================== ==================== Terri Lee (408) 555-1234 Oliver H. Bender (408) 555-1234 Mary S. MacDonald (415) 555-1234 Michael Yanowski (415) 555-1234 Robert Nelson (408) 555-1234 Kelly Brown (408) 555-1234 Stewart Hall (408) 555-1234 ... Отметим, что PHONE_LIST - это виртуальная таблица (представление), созданная в InterBase и основанная на информации из двух таблиц - EMPLOYEE и DEPARTMENT. Она не показана на рис.1, однако, как мы уже указывали в общей структуре команды SELECT, к ней можно обращаться так же, как и к “настоящей” таблице.
FROM phone_list
получить список служебных
телефонов
EMP_NO FIRST_NAME LAST_NAME PHONE_EXT LOCATION PHONE_NO ====== ========== ========= ========= ============= ============== 12 Terri Lee 256 Monterey (408) 555-1234 105 Oliver H. Bender 255 Monterey (408) 555-1234 85 Mary S. MacDonald 477 San Francisco (415) 555-1234 127 Michael Yanowski 492 San Francisco (415) 555-1234 2 Robert Nelson 250 Monterey (408) 555-1234 109 Kelly Brown 202 Monterey (408) 555-1234 14 Stewart Hall 227 Monterey (408) 555-1234 ...
FROM phone_list
получить список служебных
телефонов
FIRST_NAME LAST_NAME PHONE_NO LOCATION PHONE_EXT EMP_NO ========== ========= ============== ============= ========= ====== Terri Lee (408) 555-1234 Monterey 256 12 Oliver H. Bender (408) 555-1234 Monterey 255 105 Mary S. MacDonald (415) 555-1234 San Francisco 477 85 Michael Yanowski (415) 555-1234 San Francisco 492 127 Robert Nelson (408) 555-1234 Monterey 250 2 Kelly Brown (408) 555-1234 Monterey 202 109 Stewart Hall (408) 555-1234 Monterey 227 14 ...
SELECT
job_requirement
JOB_REQUIREMENT: No specific requirements. JOB_REQUIREMENT: 15+ years in finance or 5+ years as a CFO with a proven track record. MBA or J.D. degree. ...
FROM employee
получить список номеров
EMP_NO SALARY ====== ====================== ====================== 2 105900.00 121785 4 97500.00 112125 5 102750.00 118162.5 8 64635.00 74330.25 9 75060.00 86319 11 86292.94 99236.87812499999 12 53793.00 61861.95 14 69482.62 79905.01874999999 ... Порядок вычисления выражений подчиняется общепринятым правилам: сначала выполняется умножение и деление, а затем - сложение и вычитание. Операции одного уровня выполняются слева направо. Разрешено применять скобки для изменения порядка вычислений. Например, в выражении col1 + col2 * col3 сначала находится произведение значений столбцов col2 и col3, а затем результат этого умножения складывается со значением столбца col1. А в выражении (col1 + col2) * col3 сначала выполняется сложение значений столбцов col1 и col2, и только после этого результат умножается на значение столбца col3.
SELECT first_name, "получает", salary, "долларов в год" FROM employee
получить список сотрудников
FIRST_NAME SALARY =========== ======== ========== ============== Robert получает 105900.00 долларов в год Bruce получает 97500.00 долларов в год Kim получает 102750.00 долларов в год Leslie получает 64635.00 долларов в год Phil получает 75060.00 долларов в год K. J. получает 86292.94 долларов в год Terri получает 53793.00 долларов в год ...
SELECT "сотрудник " || first_name || " " || last_name FROM employee получить список всех сотрудников ============================================== сотрудник Robert Nelson сотрудник Bruce Young сотрудник Kim Lambert сотрудник Leslie Johnson сотрудник Phil Forest сотрудник K. J. Weston сотрудник Terri Lee сотрудник Stewart Hall ...
SELECT count(*) AS number FROM employee подсчитать количество служащих NUMBER =========== 42 SELECT "сотрудник " || first_name || " " || last_name AS employee_list FROM employee получить список всех сотрудников EMPLOYEE_LIST ============================================== сотрудник Robert Nelson сотрудник Bruce Young сотрудник Kim Lambert сотрудник Leslie Johnson сотрудник Phil Forest сотрудник K. J. Weston сотрудник Terri Lee сотрудник Stewart Hall ...
FROM employee WHERE hire_date
> '1-1-94' получить
список сотрудников,
=============== ==================== =========== Pierre Osborne 3-JAN-1994 John Montgomery 30-MAR-1994 Mark Guckenheimer 2-MAY-1994
FROM employee WHERE 'today'
- hire_date > 365 * 7 + 1
=============== ==================== =========== Robert Nelson 28-DEC-1988 Bruce Young 28-DEC-1988
SELECT count(*), sum (budget), avg (budget), min (budget), max (budget) FROM department WHERE head_dept
= 100 вычислить:
количество отделов,
COUNT SUM AVG MIN MAX ====== =========== ========== ========== =========== 5 3800000.00 760000.00 500000.00 1500000.00 Типы предикатов, используемых в предложении WHERE:
<> не равно != не равно > больше < меньше >= больше или равно <= меньше или равно
Что же может быть элементом сравнения? Элементом сравнения может выступать:
FROM employee WHERE job_code
= "Admin" получить
список сотрудников
=============== ==================== ======= Terri Lee 000 Ann Bennet 120 Sue Anne O'Brien 670 Kelly Brown 600 SELECT first_name, last_name, dept_no, job_country FROM employee WHERE job_country
<> "USA" получить
список сотрудников
=============== ================ ======= ============== Ann Bennet 120 England Roger Reeves 120 England Willie Stansbury 120 England Claudia Sutherland 140 Canada Yuki Ichida 115 Japan Takashi Yamamoto 115 Japan Roberto Ferrari 125 Italy Jacques Glon 123 France Pierre Osborne 121 Switzerland
SELECT first_name, last_name, salary FROM employee WHERE salary
BETWEEN 20000 AND 30000
FIRST_NAME LAST_NAME SALARY =============== ========== =============== Ann Bennet 22935.00 Kelly Brown 27000.00 Тот же запрос с использованием операторов сравнения будет выглядеть следующим образом: SELECT first_name, last_name, salary FROM employee WHERE salary >= 20000 AND salary
<= 30000 получить
список сотрудников,
FIRST_NAME LAST_NAME SALARY =============== ========== =============== Ann Bennet 22935.00 Kelly Brown 27000.00 Запрос с предикатом BETWEEN может иметь следующий вид: SELECT first_name, last_name, salary FROM employee WHERE last_name
BETWEEN "Nelson" AND "Osborne"
FIRST_NAME LAST_NAME SALARY =============== =============== ================ Robert Nelson 105900.00 Carol Nordstrom 42742.50 Sue Anne O'Brien 31275.00 Pierre Osborne 110000.00 Значения, определяющие нижний и верхний диапазоны, могут не являться реальными величинами из базы данных. И это очень удобно - ведь мы не всегда можем указать точные значения диапазонов! SELECT first_name, last_name, salary FROM employee WHERE last_name
BETWEEN "Nel" AND "Osb"
FIRST_NAME LAST_NAME SALARY =============== =============== ================ Robert Nelson 105900.00 Carol Nordstrom 42742.50 Sue Anne O'Brien 31275.00 В данном примере значений “Nel” и “Osb” в базе данных нет. Однако, все сотрудники, входящие в диапазон, в нижней части которого начало фамилий совпадает с “Nel” (т.е. выполняется условие “больше или равно”), а в верхней части фамилия не более “Osb” (т.е. выполняется условие “меньше или равно” - а именно “O”, “Os”, “Osb”), попадут в выборку. Отметим, что при выборке с использованием предиката BETWEEN поле, на которое накладывается диапазон, считается упорядоченным по возрастанию. Предикат BETWEEN с отрицанием NOT (NOT BETWEEN) позволяет получить выборку записей, указанные поля которых имеют значения меньше нижней границы и больше верхней границы. SELECT first_name, last_name, hire_date FROM employee WHERE hire_date
NOT BETWEEN "1-JAN-1989" AND "31-DEC-1993" получить
список самых “старых”
FIRST_NAME LAST_NAME HIRE_DATE =============== ================ =========== Robert Nelson 28-DEC-1988 Bruce Young 28-DEC-1988 Pierre Osborne 3-JAN-1994 John Montgomery 30-MAR-1994 Mark Guckenheimer 2-MAY-1994
SELECT first_name, last_name, job_code FROM employee WHERE job_code
IN ("VP", "Admin", "Finan")
FIRST_NAME LAST_NAME JOB_CODE =============== ================ ======== Robert Nelson VP Terri Lee Admin Stewart Hall Finan Ann Bennet Admin Sue Anne O'Brien Admin Mary S. MacDonald VP Kelly Brown Admin А вот пример запроса, использующего предикат NOT IN: SELECT first_name, last_name, job_country FROM employee WHERE job_country NOT IN ("USA",
"Japan", "England")
FIRST_NAME LAST_NAME JOB_COUNTRY =============== ================ =============== Claudia Sutherland Canada Roberto Ferrari Italy Jacques Glon France Pierre Osborne Switzerland
% - замещает любое количество символов (в том числе и 0), _ - замещает только один символ. Разрешено также использовать конструкцию NOT LIKE. SELECT first_name, last_name FROM employee WHERE last_name
LIKE "F%" получить
список сотрудников,
FIRST_NAME LAST_NAME =============== ==================== Phil Forest Pete Fisher Roberto Ferrari SELECT first_name, last_name FROM employee WHERE first_name
LIKE "%er" получить
список сотрудников,
FIRST_NAME LAST_NAME =============== ==================== Roger De Souza Roger Reeves Walter Steadman А такой запрос позволяет решить проблему произношения (и написания) имени: SELECT first_name, last_name FROM employee WHERE first_name
LIKE "Jacq_es"
FIRST_NAME LAST_NAME =============== ==================== Jacques Glon Что делать, если требуется найти строку, которая содержит указанные выше специальные символы (“%”, “_”) в качестве информационных символов? Есть выход! Для этого с помощью ключевого слова ESCAPE нужно определить так называемый escape-символ, который, будучи поставленным перед символом “%” или “_”, укажет, что этот символ является информационным. Escape-символ не может быть символом “\” (обратная косая черта) и, вообще говоря, должен представлять собой символ, никогда не появляющийся в упоминаемом столбце как информационный символ. Часто для этих целей используются символы “@” и “~”. SELECT first_name, last_name FROM employee WHERE first_name
LIKE "%@_%" ESCAPE "@"
SELECT first_name, last_name FROM employee WHERE last_name
CONTAINING "ne"
FIRST_NAME LAST_NAME =============== ==================== Robert Nelson Ann Bennet Pierre Osborne
WHERE dept_no = NULL или даже WHERE NULL = NULL. Предикат IS NULL принимает значение true только тогда, когда выражение слева от ключевых слов “IS NULL” имеет значение null (пусто, не определено). Разрешено также использовать конструкцию IS NOT NULL, которая означает “не пусто”, “имеет какое-либо значение”. SELECT department, mngr_no FROM department WHERE mngr_no
IS NULL получить
список отделов,
DEPARTMENT MNGR_NO ========================= ======= Marketing <null> Software Products Div. <null> Software Development <null> Field Office: Singapore <null> Предикаты EXIST, ANY, ALL,
SOME, SINGULAR мы рассмотрим в разделе, рассказывающем о подзапросах.
Оператор AND означает, что общий предикат будет истинным только тогда, когда условия, связанные по “AND”, будут истинны. Оператор OR означает, что общий предикат будет истинным, когда хотя бы одно из условий, связанных по “OR”, будет истинным. Оператор NOT означает, что общий предикат будет истинным, когда условие, перед которым стоит этот оператор, будет ложным. В одном предикате логические операторы выполняются в следующем порядке: сначала выполняется оператор NOT, затем - AND и только после этого - оператор OR. Для изменения порядка выполнения операторов разрешается использовать скобки. SELECT first_name, last_name, dept_no, job_code, salary FROM employee WHERE dept_no = 622 OR job_code = "Eng" AND salary <= 40000 ORDER BY
last_name получить
список служащих,
============ ============= ======= ======== =========== Jennifer M. Burbank 622 Eng 53167.50 Phil Forest 622 Mngr 75060.00 T.J. Green 621 Eng 36000.00 Mark Guckenheimer 622 Eng 32000.00 John Montgomery 672 Eng 35000.00 Bill Parker 623 Eng 35000.00 Willie Stansbury 120
Eng 39224.06
job_code, salary FROM employee WHERE (dept_no = 622 OR job_code = "Eng") AND salary <= 40000 ORDER BY
last_name получить
список служащих,
============ ============= ======= ======== =========== T.J. Green 621 Eng 36000.00 Mark Guckenheimer 622 Eng 32000.00 John Montgomery 672 Eng 35000.00 Bill Parker 623 Eng 35000.00 Willie Stansbury 120
Eng 39224.06
Типы данных могут быть конвертированы в соответствии со следующей таблицей: Из типа данных В тип данных --------------------------------------- NUMERIC CHAR, VARCHAR, DATE CHAR, VARCHAR NUMERIC, DATE DATE CHAR, VARCHAR, DATE
SELECT first_name, last_name, dept_no FROM employee WHERE CAST(dept_no AS char(20)) CONTAINING
"00" получить список
сотрудников,
FIRST_NAME LAST_NAME DEPT_NO =============== ==================== ======= Robert Nelson 600 Terri Lee 000 Stewart Hall 900 Walter Steadman 900 Mary S. MacDonald 100 Oliver H. Bender 000 Kelly Brown 600 Michael Yanowski 100
Порядок строк может задаваться одним из двух способов:
Подчеркнем еще раз, что предложение ORDER BY должно указываться в самом конце запроса.
job_code, salary FROM employee ORDER BY
last_name получить
список сотрудников,
FIRST_NAME LAST_NAME DEPT_NO JOB_CODE SALARY ============ ============= ======= ======== =========== Janet Baldwin 110 Sales 61637.81 Oliver H. Bender 000 CEO 212850.00 Ann Bennet 120 Admin 22935.00 Dana Bishop 621 Eng 62550.00 Kelly Brown 600 Admin 27000.00 Jennifer M. Burbank 622 Eng 53167.50 Kevin Cook 670 Dir 111262.50 Roger De Souza 623 Eng 69482.62 Roberto Ferrari 125 SRep 99000000.00 ...
SELECT first_name, last_name, dept_no, job_code, salary FROM employee ORDER BY
last_name DESC получить
список сотрудников,
FIRST_NAME LAST_NAME DEPT_NO JOB_CODE SALARY ============ ============= ======= ======== =========== Katherine Young 623 Mngr 67241.25 Bruce Young 621 Eng 97500.00 Michael Yanowski 100 SRep 44000.00 Takashi Yamamoto 115 SRep 7480000.00 Randy Williams 672 Mngr 56295.00 K. J. Weston 130 SRep 86292.94 Claudia Sutherland 140 SRep 100914.00 Walter Steadman 900 CFO 116100.00 Willie Stansbury 120 Eng 39224.06 Roger Reeves 120 Sales 33620.62 ... Столбец, определяющий порядок вывода строк, не обязательно дожен присутствовать в списке выбираемых элементов (столбцов): SELECT first_name, last_name, dept_no, job_code FROM employee ORDER BY
salary получить список
сотрудников,
FIRST_NAME LAST_NAME DEPT_NO JOB_CODE =============== =============== ======= ======== Ann Bennet 120 Admin Kelly Brown 600 Admin Sue Anne O'Brien 670 Admin Mark Guckenheimer 622 Eng Roger Reeves 120 Sales Bill Parker 623 Eng job_code, salary * 1.1 FROM employee ORDER BY
5 получить список
сотрудников,
============ ============= ======= ======== =========== Ann Bennet 120 Admin 25228.5 Kelly Brown 600 Admin 29700 Sue Anne O'Brien 670 Admin 34402.5 Mark Guckenheimer 622 Eng 35200 Roger Reeves 120 Sales 36982.6875 Bill Parker 623 Eng 38500
job_code, salary * 1.1 FROM employee ORDER BY
dept_no, 5 DESC, last_name
=========== ========== ======= ======== =============== Oliver H. Bender 000 CEO 234135 Terri Lee 000 Admin 59172.3 Mary S. MacDonald 100 VP 122388.75 Michael Yanowski 100 SRep 48400.000000001 Luke Leung 110 SRep 75685.5 Janet Baldwin 110 Sales 67801.59375 Takashi Yamamoto 115 SRep 8228000.0000001 Yuki Ichida 115 Eng 6600000.0000001
Иногда (в зависимости от задачи) бывает необходимо устранить все повторы строк из результирующего набора. Этой цели служит модификатор DISTINCT. Данный модификатор может быть указан только один раз в списке выбираемых элементов и действует на весь список. SELECT job_code FROM employee получить список должностей сотрудников JOB_CODE ======== VP Eng Eng Mktg Mngr SRep Admin Finan Mngr Mngr Eng ... Данный пример некорректно решает задачу “получения” списка должностей сотрудников предприятия, так как в нем имеются многочисленные повторы, затрудняющие восприятие информации. Тот же запрос, включающий модификатор DISTINCT, устраняющий дублирование, дает верный результат. SELECT DISTINCT job_code FROM employee получить список должностей сотрудников JOB_CODE ======== Admin CEO CFO Dir Doc Eng Finan Mktg Mngr PRel SRep Sales VP Два следующих примера показывают, что модификатор DISTINCT действует на всю строку сразу. SELECT first_name, last_name FROM employee WHERE first_name
= "Roger" получить
список служащих,
FIRST_NAME LAST_NAME =============== ==================== Roger De Souza Roger Reeves
SELECT DISTINCT first_name, last_name FROM employee WHERE first_name
= "Roger" получить
список служащих,
FIRST_NAME LAST_NAME =============== ==================== Roger De Souza Roger Reeves
После изучения этого раздела мы будем способны:
Связывание производится,
как правило, по первичному ключу одной таблицы и внешнему ключу другой
таблицы - для каждой пары таблиц. При этом очень важно учитывать все поля
внешнего ключа, иначе результат будет искажен. Соединяемые поля могут (но
не обязаны!) присутствовать в списке выбираемых элементов. Предложение
WHERE может содержать множественные условия соединений. Условие соединения
может также комбинироваться с другими предикатами в предложении WHERE.
FROM employee, department WHERE job_code
= "VP" получить список
сотрудников,
=============== ================ ====================== Robert Nelson Corporate Headquarters Mary S. MacDonald Corporate Headquarters Robert Nelson Sales and Marketing Mary S. MacDonald Sales and Marketing Robert Nelson Engineering Mary S. MacDonald Engineering Robert Nelson Finance Mary S. MacDonald Finance ...
FROM employee, department WHERE job_code = "VP" AND employee.dept_no = department.dept_no имена таблиц получить список сотрудников,
=============== ================ ====================== Robert Nelson Engineering Mary S. MacDonald Sales
and Marketing
Замечание 1: в одном запросе нельзя смешивать использование написания имен таблиц и их алиасов. Замечание 2: алиасы
таблиц могут совпадать с их именами.
FROM employee e, department d WHERE job_code = "VP" AND e.dept_no = d.dept_no алиасы таблиц получить список сотрудников,
=============== ================ ====================== Robert Nelson Engineering Mary S. MacDonald Sales
and Marketing
department FROM employee e, department d, job j WHERE d.mngr_no = e.emp_no AND e.job_code = j.job_code AND e.job_grade = j.job_grade AND e.job_country
= j.job_country
========== ============ ======================= ====================== Robert Nelson Vice President Engineering Phil Forest Manager Quality Assurance K. J. Weston Sales Representative Field Office: East Coast Katherine Young Manager Customer Support Chris Papadopoulos Manager Research and Development Janet Baldwin Sales Co-ordinator Pacific Rim Headquarters Roger Reeves Sales Co-ordinator European Headquarters Walter Steadman Chief Financial Officer Finance В данном примере последние три условия необходимы в силу того, что первичный ключ в таблице JOB состоит из трех полей - см. рис.1. Мы рассмотрели внутренние соединения с использованием стандарта ANSI-89. Теперь опишем новый (ANSI-92) стандарт:
FROM employee e JOIN department d ON e.dept_no = d.dept_no AND department = "Customer Support" WHERE last_name
starting with "P"
============= =============== =================== Leslie Phong Customer Support Bill Parker Customer
Support
SELECT one.last_name, two.last_name, one.hire_date FROM employee one, employee two WHERE one.hire_date = two.hire_date AND one.emp_no
< two.emp_no
LAST_NAME LAST_NAME HIRE_DATE ==================== ==================== =========== Nelson Young 28-DEC-1988 Reeves Stansbury 25-APR-1991 Bishop MacDonald 1-JUN-1992 Brown Ichida 4-FEB-1993
SELECT d1.department, d2.department, d1.budget FROM department d1, department d2 WHERE d1.budget = d2.budget AND d1.dept_no
< d2.dept_no
DEPARTMENT DEPARTMENT BUDGET ======================== ========================= ========= Software Development Finance 400000.00 Field Office: East Coast Field Office: Canada 500000.00 Field Office: Japan Field Office: East Coast 500000.00 Field Office: Japan Field Office: Canada 500000.00 Field Office: Japan Field Office: Switzerland 500000.00 Field Office: Singapore Quality Assurance 300000.00 Field Office: Switzerland
Field Office: East Coast 500000.00
Вспомним, запрос вида SELECT first_name, last_name, department FROM employee e, department d WHERE e.dept_no
= d.dept_no
Внешнее соединение возвращает все строки из одной таблицы и только те строки из другой таблицы, для которых условие соединения принимает значение true. Строки второй таблицы, не удовлетворяющие условию соединения (т.е. имеющие значение false), получают значение null в результирующем наборе. Существует два вида внешнего соединения: LEFT JOIN и RIGHT JOIN. В левом соединении (LEFT JOIN) запрос возвращает все строки из левой таблицы (т.е. таблицы, стоящей слева от зарезервированного словосочетания “LEFT JOIN”) и только те из правой таблицы, которые удовлетворяют условию соединения. Если же в правой таблице не найдется строк, удовлетворяющих заданному условию, то в результате они замещаются значениями null. Для правого соединения - все наоборот. SELECT first_name, last_name, department FROM employee e LEFT JOIN department d ON e.dept_no
= d.dept_no
=============== ============== ===================== Robert Nelson Engineering Bruce Young Software Development Kim Lambert Field Office: East Coast Leslie Johnson Marketing Phil Forest Quality Assurance ...
А вот пример правого соединения: SELECT first_name, last_name, department FROM employee e RIGHT JOIN department d ON e.dept_no
= d.dept_no
=============== ============= ========================= Terri Lee Corporate Headquarters Oliver H. Bender Corporate Headquarters Mary S. MacDonald Sales and Marketing Michael Yanowski Sales and Marketing Robert Nelson Engineering Kelly Brown Engineering Stewart Hall Finance Walter Steadman Finance Leslie Johnson Marketing Carol Nordstrom Marketing <null> <null> Software Products Div. Bruce Young Software Development ...
Внимание! Если у вас не получилось найти нужную информацию, используйте рубрикатор или воспользуйтесь поиском . книги по программированию исходники компоненты шаблоны сайтов C++ PHP Delphi скачать |
|