alan_beaulieu-learning_sql-ru (865932), страница 13
Текст из файла (страница 13)
Поэтому прошу дождаться главы 8, где полностью описано, как и когда использовать group byи having.66Глава 3. Азбука запросовБлок order byВ общем случае строки результирующего набора запроса возвращаются в произвольном порядке. Если требуется упорядочить результирующий набор определенным образом, необходимо предписать серверу сортировать результаты с помощью блока order by:Блок order by – это механизм сортировки результирующего набора на основе данных столбцов, или выражений, использующих данные столбцов.Вот, к примеру, еще один взгляд на приведенный ранее запрос к таблице account:mysql> SELECT open_emp_id, product_cd> FROM account;+++| open_emp_id | product_cd |+++|10 | CHK||10 | SAV||10 | CD||10 | CHK||10 | SAV||13 | CHK||13 | MM||1 | CHK||1 | SAV||1 | MM||16 | CHK||1 | CHK||1 | CD||10 | CD||16 | CHK||16 | SAV||1 | CHK||1 | MM||1 | CD||16 | CHK||16 | BUS||10 | BUS||16 | CHK||13 | SBL|+++24 rows in set (0.00 sec)Если требуется проанализировать данные каждого сотрудника, полезно было бы отсортировать результаты по столбцу open_emp_id.
Для этого просто добавляем этот столбец в блок order by:mysql> SELECT open_emp_id, product_cd> FROM account> ORDER BY open_emp_id;Блок order by67+++| open_emp_id | product_cd |+++|1 | CHK||1 | SAV||1 | MM||1 | CHK||1 | CD||1 | CHK||1 | MM||1 | CD||10 | CHK||10 | SAV||10 | CD||10 | CHK||10 | SAV||10 | CD||10 | BUS||13 | CHK||13 | MM||13 | SBL||16 | CHK||16 | CHK||16 | SAV||16 | CHK||16 | BUS||16 | CHK|+++24 rows in set (0.00 sec)Теперь легче увидеть, какие типы счетов были открыты каждым сотрудником. Однако было бы гораздо лучше, если бы типы счетов длякаждого отдельного сотрудника выводились в определенном порядке;это осуществляется путем добавления в блок order by столбца product_cdпосле open_emp_id:mysql> SELECT open_emp_id, product_cd> FROM account> ORDER BY open_emp_id, product_cd;+++| open_emp_id | product_cd |+++|1 | CD||1 | CD||1 | CHK||1 | CHK||1 | CHK||1 | MM||1 | MM||1 | SAV||10 | BUS|68Глава 3.
Азбука запросов|10 | CD||10 | CD||10 | CHK||10 | CHK||10 | SAV||10 | SAV||13 | CHK||13 | MM||13 | SBL||16 | BUS||16 | CHK||16 | CHK||16 | CHK||16 | CHK||16 | SAV|+++24 rows in set (0.00 sec)Теперь результирующий набор отсортирован сначала по ID сотрудников, а затем по типу счета. Учитывается порядок размещения столбцов в блоке order by.Сортировка по возрастанию и убываниюПри сортировке можно задать порядок по возрастанию (ascending)или по убыванию (descending) с помощью ключевых слов asc и desc.По умолчанию выполняется сортировка по возрастанию, поэтому добавлять придется только ключевое слово desc – если требуется сортировка по убыванию.
Например, по следующему запросу выводитсясписок всех счетов, отсортированный по доступному остатку, начинаяс самого большого:mysql> SELECT account_id, product_cd, open_date, avail_balance> FROM account> ORDER BY avail_balance DESC;+++++| account_id | product_cd | open_date | avail_balance |+++++|24 | SBL| 20040222 |50000.00 ||23 | CHK| 20030730 |38552.05 ||20 | CHK| 20020930 |23575.12 ||13 | CD| 20041228 |10000.00 ||22 | BUS| 20040322 |9345.55 ||18 | MM| 20041028 |9345.55 ||10 | MM| 20040930 |5487.09 ||14 | CD| 20040112 |5000.00 ||15 | CHK| 20010523 |3487.19 ||3 | CD| 20040630 |3000.00 ||4 | CHK| 20010312 |2258.02 ||11 | CHK| 20040127 |2237.97 ||7 | MM| 20021215 |2212.50 ||19 | CD| 20040630 |1500.00 |Блок order by69|1 | CHK| 20000115 |1057.75 ||6 | CHK| 20021123 |1057.75 ||9 | SAV| 20000115 |767.77 ||8 | CHK| 20030912 |534.12 ||2 | SAV| 20000115 |500.00 ||16 | SAV| 20010523 |387.99 ||5 | SAV| 20010312 |200.00 ||17 | CHK| 20030730 |125.67 ||12 | CHK| 20020824 |122.37 ||21 | BUS| 20021001 |0.00 |+++++24 rows in set (0.01 sec)Сортировка по убыванию обычно применяется в ранжирующих запросах вроде «покажи мне пять самых больших доступных остатков».MySQL включает блок limit (предел), позволяющий сортировать данные и затем отбрасывать все, кроме первых X строк.
Блок limit обсуждается в приложении В вместе с другими расширениями, не входящими в стандарт ANSI.Сортировка с помощью выраженийСортировать результаты по данным столбца легко и приятно, но иногда может потребоваться сортировка по какомуто признаку, которыйне хранится в БД и, возможно, отсутствует в запросе.
Чтобы справиться с этой ситуацией, можно добавить в блок order by выражение. Например, требуется сортировать данные клиентов по последним тремразрядам их федерального ID (это либо номер социальной страховкидля физических лиц, либо корпоративный ID для юридических лиц):mysql> SELECT cust_id, cust_type_cd, city, state, fed_id> FROM customer> ORDER BY RIGHT(fed_id, 3);++++++| cust_id | cust_type_cd | city| state | fed_id|++++++|1 | I| Lynnfield | MA| 111111111 ||10 | B| Salem| NH| 041111111 ||2 | I| Woburn| MA| 222222222 ||11 | B| Wilmington | MA| 042222222 ||3 | I| Quincy| MA| 333333333 ||12 | B| Salem| NH| 043333333 ||13 | B| Quincy| MA| 044444444 ||4 | I| Waltham| MA| 444444444 ||5 | I| Salem| NH| 555555555 ||6 | I| Waltham| MA| 666666666 ||7 | I| Wilmington | MA| 777777777 ||8 | I| Salem| NH| 888888888 ||9 | I| Newton| MA| 999999999 |++++++13 rows in set (0.01 sec)70Глава 3. Азбука запросовВ этом запросе используется встроенная функция right(), которая извлекает последние три символа значения столбца fed_id и сортируетстроки на основании этого значения.Сортировка с помощью числовых заместителейПри сортировке с использованием столбцов, перечисленных в блоке select, можно ссылаться на столбцы не по имени, а по их порядковому номеру.
Например, если требуется выполнить сортировку по второму илипятому столбцу, возвращаемому запросом, можно сделать следующее:mysql> SELECT emp_id, title, start_date, fname, lname> FROM employee> ORDER BY 2, 5;++++++| emp_id | title| start_date | fname| lname|++++++|13 | Head Teller| 20000511 | John| Blake||6 | Head Teller| 20040317 | Helen| Fleming ||16 | Head Teller| 20010315 | Theresa | Markham ||10 | Head Teller| 20020727 | Paula| Roberts ||5 | Loan Manager| 20031114 | John| Gooding ||4 | Operations Manager | 20020424 | Susan| Hawthorne ||1 | President| 20010622 | Michael | Smith||17 | Teller| 20020629 | Beth| Fowler||9 | Teller| 20020503 | Jane| Grossman ||12 | Teller| 20030108 | Samantha | Jameson ||14 | Teller| 20020809 | Cindy| Mason||8 | Teller| 20021202 | Sarah| Parker||15 | Teller| 20030401 | Frank| Portman ||7 | Teller| 20040915 | Chris| Tucker||18 | Teller| 20021212 | Rick| Tulman||11 | Teller| 20001023 | Thomas | Ziegler ||3 | Treasurer| 20000209 | Robert | Tyler||2 | Vice President| 20020912 | Susan| Barker|++++++18 rows in set (0.03 sec)Скорее всего, вы редко будете использовать эту возможность, поскольку если добавить столбец в блок select и не изменить порядковые номера в блоке order by, результаты будут непредсказуемыми.УпражненияСледующие упражнения разработаны для закрепления пониманиявыражения select и его блоков.
Решения приведены в приложении С.3.1Извлеките ID, имя и фамилию всех банковских сотрудников. Выполните сортировку по фамилии, а затем по имени.Упражнения713.2Извлеките ID счета, ID клиента и доступный остаток всех счетов, имеющих статус 'ACTIVE' (активный) и доступный остаток более 2500 долларов.3.3Напишите запрос к таблице account, возвращающий ID сотрудников, отрывших счета (используйте столбец account.open_emp_id).
Результирующий набор должен включать по одной строке для каждого сотрудника.3.4В этом запросе к нескольким наборам данных заполните пробелы (обозначенные как <число>) так, чтобы получить результат, приведенныйниже:mysql> SELECT p.product_cd, a.cust_id, a.avail_balance> FROM product p INNER JOIN account <1>> ON p.product_cd = <2>> WHERE p.<3> = 'ACCOUNT';++++| product_cd | cust_id | avail_balance |++++| CD|1 |3000.00 || CD|6 |10000.00 || CD|7 |5000.00 || CD|9 |1500.00 || CHK|1 |1057.75 || CHK|2 |2258.02 || CHK|3 |1057.75 || CHK|4 |534.12 || CHK|5 |2237.97 || CHK|6 |122.37 || CHK|8 |3487.19 || CHK|9 |125.67 || CHK|10 |23575.12 || CHK|12 |38552.05 || MM|3 |2212.50 || MM|4 |5487.09 || MM|9 |9345.55 || SAV|1 |500.00 || SAV|2 |200.00 || SAV|4 |767.77 || SAV|8 |387.99 |++++21 rows in set (0.02 sec)ФильтрацияБывают случаи, когда требуется работать со всеми строками таблицы,например:•Удаление всех данных таблицы для того, чтобы загрузить новыеданные из другого источника.•Изменение всех строк таблицы после добавления нового столбца.•Извлечение всех строк из таблицы очереди сообщений.В подобных случаях SQLвыражениям не нужен блок where, посколькунет необходимости исключать из рассмотрения какиелибо строки.Однако чаще всего требуется сужать фокус и работать с подмножеством строк таблицы.