[18-10-2009] Джо

GROUP BY и HAVING. Отличие в использовании HAVING и WHERE

Начало статьи об операторе SELECT

GROUP BY группирует результат SELECT по значениям какого-либо поля ( полей ). Использовать GROUP BY имеет смысл только вместе с одной из аналитических групповых функций

MAX() - максимальное значение в колонке

MIN()- минимальное значение в колонке

COUNT() - количество значений в колонке

SUM() - сумма всех значений в колонке

AVG() - среднее значение

К примеру, если нужно узнать из таблиц, определенных в 1й части статьи, магазины, в которых минимальные цены на рюкзаки, и сами минимальные цены, необходимо сделать следующий запрос:

SELECT rkz.nazv, ts.mag, MIN(ts.tsena) FROM ts,rkz WHERE rkz.nazv=ts.nazv GROUP BY rkz.nazv

Результат выполнения запроса:

nazvmagtsena
KATANGA 60Спортбаза8092
KIMBERLY 80 1404Спортбаза7500
Lhotse CD-100Спортбаза3850
Атлант - 90Туритура3070
Кондор 80Спортбаза890

Если нужно ограничить значение минимальной цены, нужно использовать предложение HAVING:

SELECT rkz.nazv, ts.mag, MIN(ts.tsena) FROM ts,rkz WHERE rkz.nazv=ts.nazv GROUP BY rkz.nazv HAVING MIN(ts.tsena)<5000

Результат выполнения запроса:

nazvmagtsena
Lhotse CD-100Спортбаза3850
Атлант - 90Туритура3070
Кондор 80Спортбаза890

Если необходимо выбрать только рюкзаки с литражом больше 80 литров, условие добавляется в предложение WHERE:

SELECT rkz.nazv, ts.mag, MIN(ts.tsena) FROM ts,rkz WHERE rkz.nazv=ts.nazv AND rkz.litr>80 GROUP BY rkz.nazv HAVING MIN(ts.tsena)<5000

Результат выполнения запроса:

nazvmagtsena
Lhotse CD-100Спортбаза3850
Атлант - 90Туритура3070

Видно, что при вводе ограничения на значение групповой операции используется HAVING, а при введении ограничения на значение поля - WHERE

Упорядочивание результата запроса. ORDER BY. DESC.

Упорядочить результат выполнения запроса для его анализа имеет смысл, если результат ожидается достаточно большим.

К примеру, запрос из Начала статьи об операторе SELECT будет иметь такой вид:

SELECT rkz.nazv, rkz.litr, ts.mag, ts.tsena FROM ts,rkz WHERE rkz.nazv=ts.nazv ORDER BY rkz.nazv

Результат выполнения запроса:

nazvlitrmagtsena
KATANGA 6060Туристёнок8092
KATANGA 6060Спортбаза8100
KATANGA 6060Туритура8105
KIMBERLY 80 140480Спортбаза7500
KIMBERLY 80 140480Туритура7600
KIMBERLY 80 140480Туристёнок7620
Lhotse CD-100100Спортбаза3850
Атлант - 9090Туритура3100
Атлант - 9090Спортбаза3070
Кондор 8080Спортбаза890
Кондор 8080Туристёнок900
Кондор 8080Туритура910

По умолчанию идет сортировка по возрастанию, если необходима сортировка по убыванию - указывается параметр DESC

SELECT rkz.nazv, rkz.litr, ts.mag, ts.tsena FROM ts,rkz WHERE rkz.nazv=ts.nazv ORDER BY rkz.nazv DESC

Результат выполнения запроса:

nazvlitrmagtsena
Кондор 8080Спортбаза890
Кондор 8080Туристёнок900
Кондор 8080Туритура910
Атлант - 9090Туритура3100
Атлант - 9090Спортбаза3070
Lhotse CD-100100Спортбаза3850
KIMBERLY 80 140480Спортбаза7500
KIMBERLY 80 140480Туритура7600
KIMBERLY 80 140480Туристёнок7620
KATANGA 6060Туристёнок8092
KATANGA 6060Спортбаза8100
KATANGA 6060Туритура8105

Ограничение результата запроса. LIMIT.

В случае очень большого количества строк в результате запроса имеет смысл ограничить количество строк. Для этого используют предложение LIMIT с 2мя числовыми параметрами: номером первой выводимой строки и количеством выводимых строк. В случае одного параметра выводится количество строк, равное этому параметру, начиная с 1й.

SELECT rkz.nazv, rkz.litr, ts.mag, ts.tsena FROM ts,rkz WHERE rkz.nazv=ts.nazv ORDER BY rkz.nazv DESC LIMIT 5

Результат выполнения запроса:

nazvlitrmagtsena
Кондор 8080Спортбаза890
Кондор 8080Туристёнок900
Кондор 8080Туритура910
Атлант - 9090Туритура3100
Атлант - 9090Спортбаза3070

SELECT rkz.nazv, rkz.litr, ts.mag, ts.tsena FROM ts,rkz WHERE rkz.nazv=ts.nazv ORDER BY rkz.nazv DESC LIMIT 3,5

Результат выполнения запроса:

nazvlitrmagtsena
Атлант - 9090Туритура3100
Атлант - 9090Спортбаза3070
Lhotse CD-100100Спортбаза3850
KIMBERLY 80 140480Спортбаза7500
KIMBERLY 80 140480Туритура7600
Сергей [ 1 ]
Спасибо большое!
Дмитрий [ 2 ]
Прошу меня извинить: я пишу не коментарий.
Я обращаюсь к Вам с просьбой.
Проблема вот в чем:
есть база;
в вомент формирования информация в ней имела сортированный как нужно вид;
при использовании навигационного меню, order by и limit все выводилось как конфетка;
для расшифровки назначения полей использовалась шапка, которая вставлялась перед выводом очередной порции по нажатию "кнопки".
Но радость была короткой.
При тестировании программы проводилось вставкой в конец таблицы строки со значением поля сортировки с расчетом на то, что после сортировки строка должна будет оказаться где-то внутри таблицы, после чего должен будет заработать limit.
И возникла проблема: все отсортировалось как надо, но во фрагменте, где находилась вставленная запись, произошла подвижка шапки вниз, хотя число записей на экране соответствовало требуемому.
Это произошло только для фрагмента со вставленной записью: дальше на экран все выводилось опять нормально. Сможете ли Вы мне помочь в решении этой проблемы ??? Спасибо за любой ответ. Лучше по E-mail.
Joe [ 3 ]
Дмитрий, зашлите мне свой e-mail с помощью формы на страничке Контакты (меню сверху страницы) - отвечу.
Вадим [ 4 ]
правильно будет так (см. часть group by)
SELECT rkz.nazv, ts.mag, MIN(ts.tsena) FROM ts,rkz WHERE rkz.nazv=ts.nazv GROUP BY rkz.nazv, ts.mag
Джо [ 5 ]
Вадим, а Вы проверили, что получается в результате выполнения Вашего запроса?
Я проверил, получается вот что:
KATANGA 60 Спортбаза 8100
KATANGA 60 Туристёнок 8092
KATANGA 60 Туритура 8105
KIMBERLY 80 1404 Спортбаза 7500
KIMBERLY 80 1404 Туристёнок 7620
KIMBERLY 80 1404 Туритура 7600
Lhotse CD-100 Спортбаза 3850
Атлант - 90 Спортбаза 3070
Атлант - 90 Туритура 3100
Кондор 80 Спортбаза 890
Кондор 80 Туристёнок 900
Кондор 80 Туритура 910
т. е. откровенно не то, что требуется по условию(магазин, в котором минимальная цена на рюкзак определенного вида).

* - обязательно заполнить

Комментарий

*Имя

E-mail

*Код: 

*Текст комментария:

Самые популярные статьи