Запрос на обновление данных в таблице
Запрос на выборку данных.
Предназначен для вывода информации из таблиц, одной или нескольких. Общий вид:
SELECT ЧТО ВЫБРАТЬ (КАКИЕ СТОЛБЦЫ) FROM ОТКУДА (ИЗ КАКОЙ ТАБЛИЦЫ) WHERE ГДЕ (УСЛОВИЯ ОТБОРА);
Самый простой вариант такого запроса:
Select * from abon;
Такой запрос выведет абсолютно все данные из таблицы ABON. Если же нужны не все записи, нужно сформулировать условия отбора, например
Select * from abon where balance < 0;
Этот запрос выведет все записи с отрицательным балансом, а именно:
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Alexander | Smirnov | -5 | 01.07.1992 | 01.01.9999 | ||||
Marina | Naumova | -89 | 03.02.1990 | 01.01.2009 | ||||
Elena | Zydkina | -9 | 04.08.2008 | 01.01.2013 |
Также, условий отбора может быть несколько. Они могут выполняться одновременно или хотя бы одно из них: если необходимо одновременное выполнение условий, они перечисляются (связываются) словом AND.Если важно хотя бы одно из них, тогда словомOR:
Select * from abon where balance < 0 and up = 6;
Такой запрос приведет к следующему результату
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Alexander | Smirnov | -5 | 01.07.1992 | 01.01.9999 |
То есть, одновременно должен быть и отрицательный баланс, и, при этом, up = 6.
Select * from abon where balance < 0 or up = 12;
Уже выдаст совсем другой результат:
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Ivan | Ivanov | 01.01.2000 | 01.01.9999 | |||||
Alexander | Smirnov | -5 | 01.07.1992 | 01.01.9999 | ||||
Marina | Naumova | -89 | 03.02.1990 | 01.01.2009 | ||||
Elena | Zydkina | -9 | 04.08.2008 | 01.01.2013 |
То есть отбираются записи, в которых либо отрицательный баланс, при этом up НЕобязательно должен быть равен 12, либо те записи, в которых up = 12, но баланс НЕобязательно отрицателен.
Также важно заметить, что при написании select * from ..., выбираются абсолютно все столбцы из таблицы. Если же все не нужны, нужно указать нужные:
Select n from abon; -выведет только один столбец. Необходимые столбцы можно перечислять через запятую:
Select n,up,nob_num from abon where balance < 0;
Результатом будет
N | UP | NOB_NUM |
Очень полезные, так называемые, итоговые функции:
COUNT - количество значений в указанном столбце
SUM - сумма значений в указанном столбце
AVG - среднее значение в указанном столбце
MIN - минимальное значение в указанном столбце
MAX - максимальное значение в указанном столбце
Select count(n) from abon where balance < 0; -отобразит количество записей с отрицательным балансом.
Select sum(balance) from abon; - отобразит сумму балансов всех абонентов.
Select avg(balance) from abon;- средний баланс у абонентов
Select min(balance) from abon; - минимальный баланс
Select max(balance) from abon; - максимальный баланс
При формировании условий отбора, также иногда лучше применять некоторые функции:
To_date –преобразовании строкового типа в строку.
Select * from abon where fd = to_date (’01.01.2000’, ‘dd.mm.yyyy’);
Данный запрос отбразит вот что:
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Ivan | Ivanov | 01.01.2000 | 01.01.9999 |
Between – определяет принадлежность к заданному периоду. Определяется двумя границами, заданными с помощью AND:
Select * from abon where balance between 40 and 100;
Данный запрос вернет все записи, баланс у которых между 40 и 100:
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Ivan | Ivanov | 01.01.2000 | 01.01.9999 | |||||
Elena | Shlyapina | 04.01.2008 | 01.01.2009 | |||||
Stepan | Shishov | 04.12.2000 | 01.01.9999 | |||||
Ivan | Syrkov | 01.01.2001 | 01.04.2010 | |||||
Petr | Legkix | 02.11.2009 | 01.01.9999 | |||||
Marina | Stolova | 03.12.1995 | 01.01.9999 |
Данный запрос можно также записать по-другому:
Select * from abon where balance > 40 and balance < 100;
Ещё пример использования этой функции:
Select * from abon where sysdate between fd and td;
Значит, что в этом запросе:
Select * from abon - выбрать все записи из таблицы abon и далее условие where sysdate between fd and td;
Sysdate – функция, возвращаемое текущее системное время.
То есть, при выполнении
Select * from abon where sysdate between fd and td;
Отобразятся все данные, которые на момент sysdate актуальны, то есть те, системная дата которых входит в период fd и td. Например, в таблице abon есть такие записи:
Elena | Shlyapina | 04.01.2008 | 01.01.2009 | |||||
Elena | Shlyapina | 02.01.2009 | 01.01.9999 |
Здесь две записи про одного и того же человека. Одинаковые значения n и up об этом явно говорят. Но, был изменен тарифный план, и, чтобы сохранить историю изменений, создалась новая запись с измененным тарифом. Обратите внимание на дату С и ПО, как она изменена. Первая запись, с тарифом 2 уже сегодня не актуальна, хоть и хранится в БД. Так вот, при выполнении запроса типа
Select * from abon where sysdate between fd and td;
эти самые неактуальные записи показываться не будут. А для того, чтобы выбрать именно неактуальные записи, нужно добавить оператор not:
Select * from abon where sysdate not between fd and td;
Этот запрос также можно записать по-другому. Вот у Вас и спрошу как J
Функция IN. Применяется, если в условиях отбора нужно указать несколько конкретных значений одного поискового поля. Может заменить множество связок OR:
Select * from abon where up in (1,3,5,9);
Согласитесь, это удобнее, нежели
Select * from abon where up = 1 or up = 3 or up = 5 or up = 9;
Также, важной особенностью является возможность сортировки полученных результатов. Для этого применяется order byполе сортировки :
Select * from abon where balance between 40 and 100 order by up;
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Stepan | Shishov | 04.12.2000 | 01.01.9999 | |||||
Elena | Shlyapina | 04.01.2008 | 01.01.2009 | |||||
Ivan | Syrkov | 01.01.2001 | 01.04.2010 | |||||
Ivan | Ivanov | 01.01.2000 | 01.01.9999 | |||||
Petr | Legkix | 02.11.2009 | 01.01.9999 | |||||
Marina | Stolova | 03.12.1995 | 01.01.9999 |
Все записи отсортированы по полюup. Также есть возможность сортировки в обратном порядке:
Select * from abon where balance between 40 and 100 order by up desc;
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Marina | Stolova | 03.12.1995 | 01.01.9999 | |||||
Petr | Legkix | 02.11.2009 | 01.01.9999 | |||||
Ivan | Ivanov | 01.01.2000 | 01.01.9999 | |||||
Ivan | Syrkov | 01.01.2001 | 01.04.2010 | |||||
Elena | Shlyapina | 04.01.2008 | 01.01.2009 | |||||
Stepan | Shishov | 04.12.2000 | 01.01.9999 |
Данные отсортированы по убыванию поля up.
Поиск по неполному совпадению строковых значений:
Иногдаточно неизвестно, по какому значению строкового поля нужно найти запись. Например, точно не помним фамилию абонента, лишь некоторые буквы. Для этого применяется макросимвол %, а также вместо знака равенства пишется like:
Select * from abon where lastname like ‘S%’;
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Alexander | Smirnov | -5 | 01.07.1992 | 01.01.9999 | ||||
Elena | Shlyapina | 04.01.2008 | 01.01.2009 | |||||
Elena | Shlyapina | 02.01.2009 | 01.01.9999 | |||||
Stepan | Shishov | 04.12.2000 | 01.01.9999 | |||||
Ivan | Syrkov | 01.01.2001 | 01.04.2010 | |||||
Ivan | Syrkov | 02.04.2010 | 01.01.9999 | |||||
Marina | Stolova | 03.12.1995 | 01.01.9999 |
Данный макросимвол можно ставить в любом месте искомого значения.
Многоуровневые запросы (по нескольким таблицам):
Эта тема не будет подробно освящаться в рамках этого документа, для начала предлагаю освоить простые запросы.Но пример, все-же приведу:
Нужно найти всех абонентов, которые платят в месяц более 300 рублей.
С одной стороны, информация о тарифах находится в форме TARIF.С другой стороны, нужно найти именно абонентов, а не тарифы. Для решения этой задачи нужно сначала найти тарифы, сумма за которые в месяц > 300 рублей, затем найти абонентов, использующие эти тарифы:
select * from abon where tarif in (select n from tarif where amount > 300);
Значит, что тут происходит:
1. Находим номера тарифов с суммой более 300: select n from tarif where amount > 300. Получаем номер 3 и 8.
2. Затем ищем абонентов с этими тарифами (попутно вспоминая фунцкцию IN). В параметры функции INпередаются значения, выполненные запросомselect n from tarif where amount > 300,т.е. фактически получается:
select * from abon where tarif in (3,8);
В результате получаем:
N | UP | FIRSTNAME | LASTNAME | NOB_NUM | TARIF | BALANCE | FD | TD |
Anna | Molkina | 04.05.2004 | 01.01.9999 | |||||
Ivan | Syrkov | 01.01.2001 | 01.04.2010 | |||||
Elena | Kolovasheva | 28.01.2005 | 01.01.2007 | |||||
Ivan | Ivanov | 01.01.2000 | 01.01.9999 |
Так как тариф 8 никто из абонентов не использует, записей с ним и нет.
По мере наработки навыков, мы ещё вернемся к подобным запросам.
Запрос на обновление данных в таблице.
Общий вид:
UPDATE ИМЯ ТАБЛИЦЫ SET ПОЛЕ=ЗНАЧЕНИЕ WHERE УСЛОВИЕ
Например,
Update abon set balance = 100500 where up = 12;
Данный запрос обновит значение поля balance на 100500. Только у той записи, где up = 12.
Условия отбора задаются идентично оператору SELECT(СМ ВЫШЕ).
Операция изменения данных является транзакции, и значит, требует подтверждения или отказа.
Подтверждение – COMMIT;
Отказ – ROLLBACK;
Подтверждение или отказ от сохранения изменений ставится после запроса на изменение.
Также нужно помнить, что есть второй вариант этого типа запроса. Пишется как обычный запрос на выборку, но с пометкой «Для обновления» for update:
Select * from abon where up = 12 for update;
После чего данные нужно будет менять в ручную и сохранить или отказаться от изменений теми же операциями commit/rollback.