MySQL. Написание сложных SELECT-запросов

Monday, 12 July 2010 | Автор: programmer

Еще раз хочу затронуть вопрос работы с MySQL. Статья по первым шагам была уже рассмотрена тут. Сейчас же попытаемся немного усложнить задачу и рассмотреть создание более сложных SQL-запросов.

Для этого нам потребуются начальные знания по SQL и конечно же терпение.

Создадим для примеров 2 таблицы: books и authors.

 
CREATE TABLE `books` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`aid` INT NOT NULL ,
	`name` CHAR( 100 ) NOT NULL ,
	`year` INT NOT NULL ,
	PRIMARY KEY (  `id` ) ,
	INDEX (  `aid` ) ,
	UNIQUE (
		`id`
	)
) ENGINE = MYISAM ;

CREATE TABLE `authors` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`author` CHAR( 50 ) NOT NULL ,
	PRIMARY KEY (  `id` ) ,
	UNIQUE (
		`id`
	)
) ENGINE = MYISAM ;

В первой таблице мы будем хранить список книг, а во второй список авторов. Связь этих двух таблиц будут осуществлять поля aid из таблицы books (id автора) и id из таблицы authors.

Теперь создадим интерфейс добавления нового автора в таблицу authors (предполагается, что соединение с базой уже есть и соединение создано через класс для работы с MySQL sql_db):

 
<?php
	if (isset($_POST['author'])) {
		if (trim($_POST['author'])!="") {
			$sql = "insert into authors (author) VALUES ('".addslashes($_POST['author'])."')";
			$db->sql_query($sql);
			echo "Автор добавлен<BR /><BR />";
		}
		else
			echo "Вы не ввели автора<BR /><BR />";
	}


	echo 'Чтобы добавить нового автора, заполните форму ниже<BR />';
	echo '<form method="POST">';
		echo '<input type="text" name="author" value="" /><BR />';
		echo '<input type="submit" value="Добавить" /><BR />';
	echo '</form>';
?>

Тоже самое делаем для книг, только при добавлении книги кроме наименовании книги нам необходимо добавить параметр "автор":

 
<?php
	if (isset($_POST['name']) && isset($_POST['author']) && is_numeric($_POST['author']) && isset($_POST['year']) && is_numeric($_POST['year'])) {
		if (trim($_POST['name'])!="") {
			$sql = "insert into books (aid, name, year) VALUES ({$_POST['author']}, '".addslashes($_POST['name'])."', {$_POST['year']})";
			$db->sql_query($sql);
			echo "Книга добавлена<BR /><BR />";
		}
		else
			echo "Вы не ввели название книги<BR /><BR />";
	}


	echo 'Чтобы добавить новую книгу, заполните форму ниже<BR />';
	echo '<form method="POST">';
		echo 'Наименование: <input type="text" name="name" value="" /><BR />';
		echo 'Год выпуска: <input type="text" name="year" value="" /><BR />';
		echo 'Автор: <select name="author">';
		$sql = "select * from authors order by author asc";
		$db->sql_query($sql);
		$authors = $db->sql_fetchrowset();
		foreach ($authors as $author) {
			echo '<option value="'.$author['id'].'">'.stripslashes($author['author']).'</option>';
		}
		echo '</select><BR />';
		echo '<input type="submit" value="Добавить" /><BR />';
	echo '</form>';
?>

Вот и готов у нас интерфейсы добавления авторов и книг, можете сами как-нибудь их разукрасить :)

А сейчас по теме статьи: организация "сложных" запросов. Сейчас попытаемся вывести названия книг вместе с авторами. Для этого составим запрос, который будет выбирать сразу данные из 2-х таблиц:

 
$sql = "select a.author, b.name from books b, authors a where b.aid=a.id";

Как видите между select и from находятся поля, которые мы будем выбирать из таблиц, это поля author из таблиц authors и name из таблицы books. Посмотрите как декларируются названия таблиц - "books b" или можно "books as b", это нужно для того, чтобы сократить длину запроса. Если бы мы не декларировали сокращенного написания названия таблиц, то запрос бы выглядел таким образом

 
$sql = "select authors.author, books.name from books, authors where books.aid=authors.id";

Согласитесь что это немного не удобно и достаточно громозко. И собственно само условие составляем таким образом, что для каждой строки из таблицы books берется значение из таблицы authors.

В конечном итоге у Вас получится что-то вроде такого:

Работа с MySQL

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

 
$sql = "select a.author, b.name from books b, authors a where b.aid=a.id order by id desc limit 0, 1";

Тут мы добавляем конструкцию "order by id desc", собственно "order by" означает, что будет сортировка, далее идет поле, по которому мы будем сортировать, в нашем случае это id, а последним параметром идет направление сортировки, у нас стоит "desc", что означает сортировку по убыванию, также можно поставить "asc" (это значение по умолчанию) и тогда сортировка будет по возрастанию. Выражение "limit 0, 1" или просто "limit 1" извещает MySQL сервер о том, что необходимо взять одну запись начиная с нулевой. Если бы мы указали "limit 1, 1", то получили предпоследнюю добавленную книгу.

P.S.: возможно такое, что при выборе из двух таблиц есть поля, которые имеют одинаковые названия, в таких случаях необходимо "переназывать" поля, делается это с помощью служебного слова в MySQL "as":

 
$sql = "select a.author, a.id, b.name, b.id as authorID from books b, authors a where b.aid=a.id";

В этом примере мы выбираем поле id из таблицы authors и называем его authorID, чтобы оно не пересекалось с полем id из таблицы books.

Скачать пример

Есть вопросы? Задавай!!!


 
Tweet


Категория(и): Изучаем PHP, MySQL

Комментарии


Tuesday, 30 November 2010 | 12:34:40 | Автор: login

В чем отличие данного способа от использования foreign key?

Tuesday, 30 November 2010 | 13:09:50 | Автор: programmer

Я конечно могу и ошибаться, но насколько я помню MYISAM не поддерживает foreign key. Речь идет тут именно про myisam, а не innodb

Отвечу на вопросы по PHP

Tuesday, 30 November 2010 | 13:55:27 | Автор: login

Да, ты прав

" Тип таблиц MyISAM не поддерживает внешние ключи, транзакции. Внешние ключи и транзакции реализованы в MySQL при использовании InnoDB таблиц. "

Добавить комментарий
Чтобы оставить комментарий, Вам необходимо зарегистрироваться или авторизироваться