![]() |
![]() |
![]() |
Удаление дубликатов и ключевое слово DISTINCT Необязательное ключевое слово DISTINCT исключает дубликаты из итогового набора. Если ключевое слово ON отсутствует, из результатов запроса с ключевым словом DISTINCT исключаются записи с повторяющимися значениями целевых полей. Проверяются только поля, входящие в целевой список SELECT. Предположим, таблица books содержит 15 записей, в каждой из которых присутствует поле authorjd. Некоторые коды авторов многократно встречаются в таблице books. Включение в запрос ключевого слова DISTINCT (листинг 4.31) гарантирует, что итоговый набор будет содержать не более одной записи для каждого автора. Листинг 4.31. Ключевое слово DISTINCT booktown=# SELECT DISTINCT author_id booktown-# FROM books; author_id 16 115 1212 1644 1809 1866 2001 2031 4156 7805 7806 15990 25041 (13 rows) booktown=# SELECT DISTINCT ON (author_id) booktown-# author_id. title booktown-# FROM books; author_id | ntitle 16 | Little Women 115 | The Tell-Tale Heart 1212 | Practical PostgreSQL 1644 | Dynamic Anatomy 1809 | The Cat in the Hat 1866 | Dune 2001 | 2001: A Space Odyssey 2031 | Goodnight Moon 4156 | The Shining 7805 | Programming Python 7806 | Perl Cookbook 15990 |Franklin in the Dark 25041 | The Velveteen Rabbit (13 rows) Первый запрос в листинге 4.31 возвращает только 13 записей из таблицы books, хотя таблица содержит 15 записей. Два автора, написавшие по две книги, вошли в итоговый набор лишь в одном экземпляре. Во втором запросе использована другая форма DISTINCT с явным перечислением полей (или выражений), проверяемых на наличие дубликатов. В этом случае запрос также возвращает 13 записей, поскольку секция ON указывает, что дубликаты проверяются по значению поля author_i d. Без секции ON запрос верн)и бы все 15 записей, поскольку по умолчанию PostgreSQL проверяет полное совпадение всех полей. В общем случае PostgreSQL выбирает записи, исключаемые из итогового набора при наличии секции ON, по своему усмотрению. Если в запрос вместе с DISTINCT входит секция ORDER BY, вы можете самостоятельно задать порядок выборки полей так, чтобы нужные записи оказались в начале. Сортировка записей рассматривается в подразделе «Сортировка записей». Если вместо исключения всех дубликатов достаточно сгруппировать записи с повторяющимися значениями некоторого критерия, воспользуйтесь секцией GROUP BY, описанной в подразделе «Группировка записей». Уточнение запросов В секции WHERE задается логическое условие, которому должны удовлетворять записи итогового набора. На практике команда SELECT почти всегда содержит как минимум одну уточняющую секцию WHERE. Предположим, вы хотите получить список всех книг о компьютерных технологиях в базе данных booktown. У этих книг поле subject_id равно 4. Соответственно в секцию WHERE включается оператор =, который проверяет это условие. Пример приведен в листинге 4.32. Листинг 4.32. Простая секция WHERE booktown=# SELECT * FROM books booktown-# WHERE subject_id = 4; id | title | author_id | subject_id 41472 | Practical PostgreSQL | 1212 | 4 41473 | Programming Python | 7805 | 4 41477 | Learning PostgreSQ L | 7805 | 4 41478 | Perl Cookbook | 7806 | 4 (4 rows) Запрос из листинга 4.32 возвращает только те записи, у которых поле subject_id совпадает с целочисленной константой 4. Итоговый набор содержит всего 4 записи книг о компьютерах вместо 15 записей, приведенных в листинге 4.23. Секция WHERE может содержать несколько условий, объединенных логическими операторами (например, AND или OR) и возвращающими одно логическое значение. Допустим, вас интересуют все записи для книг о компьютерах, которые, кроме того, что они о компьютерах, написаны Марком Лутцем. Запрос уточняется объединением двух условий при помощи логического оператора AND. Возможен и другой вариант — например, поиск всех книг, посвященных компьютерным технологиям или искусству; в этом случае два условия объединяются логическим оператором OR. В листинге 4.33 продемонстрированы оба сценария с ключевыми словами AND и OR. Листинг 4.33. Объединение условий в секции WHERE booktown=# SELECT title FROM books booktown-# WHERE subject_id = 4 booktown-# AND author_id = 7805; title Programming Python Learning Python (2 rows) booktown=# SELECT title FROM books booktown-# WHERE subject_id = 4 booktown-# AND author_id = 0; title Dynamic Anatomy Practical PostgreSQL Programming Python Learning Python Perl Cookbook (5 rows) Первая команда SELECT в листинге 4.33 содержит два условия, объединенных логическим оператором AND. Первое условие проверяет, что книга посвящена компьютерным технологиям (поле subject_id равно 4), а второе — что автором книги является Марк Лутц (поле author_id равно 7805). Объединение условий уменьшает объем итогового набора — в него входят всего две записи, удовлетворяющие обоим условиям. Во второй команде SELECT в листинге 4.33 прежнее первое условие (книги по компьютерной тематике) объединяется со вторым условием: книги по искусству (поле subject_id равно 0). В результате объем итогового набора увеличивается до пяти записей, каждая из которых удовлетворяет хотя бы одному из этих условий. Количество условий, объединяемых в секции WHERE, не ограничено, хотя при наличии двух и более условий обычно выполняется группировка при помощи круглых скобок, наглядно демонстрирующая логическую связь между условиями. Листинг 4.34 показывает, как простое добавление круглых скобок влияет на результат выполнения команды. Листинг 4.34. Группировка условий при помощи круглых скобок booktown=# SELECT * FROM books booktown-# WHERE author_id = 1866 booktown-# AND subject_id = 15 booktown-# OR subject_id = 3; id | title | autho_id | subject_id 4513 | Dune | 1866 | 15 1234 | The Velveteen Rabbit | 25041 | 3 (2 rows) booktown=# SELECT * FROM books booktown-# WHERE author_id = 1866 booktown-# AND (subject_id = 15 booktown-# OR subject_id = 3); id | title | author_id | subject_id 4513 | Dune | 1866 | 15 (1 row) В этом примере продемонстрированы две попытки выборки из базы данных booktown записей, у которых поле author_id равно 1866. Кроме того, поле subject_id должно быть равно либо 15, либо 3. Как видно из результатов первой команды, при перечислении всех трех условий без круглых скобок команда интерпретируется неправильно. Добавление круглых скобок приводит к тому, что вычисления в скобках производятся до проверки внешних условий. |
![]() |
![]() |
![]() |