КОнтакты, предложения, отзывы

.rar или .zip
Вложение
Онлайн-чат
На этом сайте, вы найдёте полезную информацию, практические советы в области веб-программирования, веб-дизайна и веб-разработок в целом. Мы с удовольствием поделимся с вами реальными примерами и решениями задач, связанных с jQuery , JavaScript , PHP и MySQL , версткой сайтов , поможем разобраться новичкам с современными технологиями, такими как Ajax , HTML5 , CSS3 и многими другими.

Сложные SQL-запросы

Вложенные запросы (подзапросы)

Подзапрос - это запрос, вложенный внутрь другого запроса. Хотя большая часть функциональности подзапросов может быть реализована за счёт использования соединений и временных таблиц, подзапросы часто легче читать и реализовавать.

Простые подзапросы

Наиболее распространённым применением подзапросов можно сччитать случай, когда результат одного запроса используется в операции сравнения, находящейся в другом запросе.
Например, предположим что мы знаем им продавца: Motika, но не знаем его номер телефона snum, и хотим извлечь всё из таблицы Orders по этому номеру. Имеется один способ чтобы сделать это
SELECT * FROM Orders  WHERE snum =  ( SELECT snum FROM Salespeople WHERE sname = 'Motika');
Чтобы оценить внешний( основной ) запрос, SQL сначала должен оценить внутренний запрос ( или подзапрос ) внутри предложения WHERE.

Подзапросы и операции

Существуют пять специальных операций подзапросов. Четыре из них используются в обычных подзапросах, и одна (EXISTS) - как правило, только в связанных (corellated) подзапросах, которые рассматриваются ниже. Каждая из этих операций может находиться только после операции сравнения, за исключением IN, которая имеет свою операцию сравнения (=), "свёрнутую внутри".

Связанные подзапросы

Связанные подзапросы более сложны в понимании. В них элементы, полученные во внешнем запросе, используются во внутреннем запросе. Например:

    select `isbn`, `title`
     from `books`
      where not exists 
       (select * from `order_items` where `order_items`.`isbn`=`books`.`isbn`);
Этот запрос извлекает все книги, которые никогда не были заказаны. Обратите внимание, что внутренний запрос включает таблицу order_items только в список from, однако ссылается на books.isbn. Другими словами, внутренний запрос ссылается на данные внешнего запроса. Это и есть определение связанного подзапроса: вы ищете строки, которые совпадают (EXISTS), или, как в рассмотренном примере, не совпадают со строками внешнего запроса.

Строковые подзапросы

Все рассмотренные до сих пор подзапросы возвращали единственное значение, которое в большинстве случаев равно true или false. строковые подзапросы возвращают целую строку, которая затем может сравниваться с целой строкой во внешнем запросе. Обычно такой подход используется для поиска строк одной таблицы, которые также существуют в другой таблице:

    select `c1`, `c2`, `c3`
     from `t1`
      where (`c1`, `c2`, `c3`) in (select `c1`, `c2`, `c3` from `t2`);

Использование подзапроса как временной таблицы

Подзапрос можно использовать в конструкции FROM внешнего запроса. Этот подход даёт возможность выполнять запрос к выходным данным подзапроса, рассматривая их как временную таблицу:

    select * from
     (select `customerid`, `name` from `customers` where `city`='г. Солнечный')  
      as `box_hill_customers`;
Непосредственно после закрывающей скобки подзапроса результату подзапроса нужно присвоить какой-то псевдоним. После этого во внешнем запросе с псевдонимом можно работать как с любой другой таблицей.

Объединение таблиц

Управление несколькими таблицами, содержащими различные виды информации в одной базе данных, считается вполне обычным делом. Основная цель такого соединения - создание нового отношения, которое будет содержать данные из двух или более исходных отношений. Часто для получения ответа от базы данных на заданный вопрос могут потребоваться данные нескольких таблиц. Для объединения этой информации в SQL потребуется выполнить операцию, называемую объединением. Например, если необходимо узнать, кто из клиентов осуществлял в этом месяце заказы, придется просмотреть таблицы Customers и Orders. Если нужно узнать, что конкретно они заказали, нельзя обойти вниманием и таблицу Order_Items. Эти данные находятся в разных таблицах, поскольку относятся к разным реальным объектам. Это один из принципов хорошей разработки базы данных. Рассмотрим, к примеру, таб­лицу клиентов — customers, для которой нужно обеспечить возможность использова­ния перекрестных ссылок с приобретенными ими книгами из таблицы classics.
SELECT  name, author, title  from  customers, classics 
WHERE  customers.isbn=classics.isbn;
Мы определили тип объединения, возможно даже не зная его. Запятая между названиями таблиц эквивалентна словам INNER JOIN или CROSS JOIN. Такой тип соединения еще называют полным объединением или Декартовым произведением таблиц. Это означает: "Возьми указанные таблицы и сделай из них одну большую. В большой таблице должна быть строка для любой возможной комбинации строк из каждой таб- лицы, указанной в списке, имеют они смысл или нет".

NATURAL JOIN

Используя NATURAL JOIN, можно сократить количество вводимого текста и сделать за­просы немного более понятными. В этом виде объединения участвуют две таблицы, в которых автоматически объединяются столбцы с одинаковыми именами. Для по­лучения тех же результатов, что и в примере выше, можно ввести следующий запрос:
SELECT  `name`. `author`. `title`  FROM  customers  NATURAL  JOIN  classics;

JOIN...ON

Если нужно указать столбец, по которому следует объединить две таблицы, ис­пользуется конструкция JOIN.. .ON, благодаря которой можно получить те же ре­зультаты, что и в предыдущем примере :
SELECT  name, author, title  FROM  customers 
JOIN  classics  ON  customers.isbn=classics.isbn;

Использование ключевого слова AS

Можно сократить количество вводимого текста и улучшить читаемость запроса за счет создания псевдонимов с помощью ключевого слова AS. После имени таблицы нужно поставить AS, а затем используемый псевдоним. Следующий код идентичен по своей работе коду, приведенному в примере выше:
SELECT  name, author, title  from 
customers  AS  cust,  classics  AS  class  WHERE  cust.isbn=class.isbn;
Псевдонимы особенно полезны в длинных запросах, содержащих множествен­ные ссылки на одни и те же имена таблиц.

Объединение трех и более таблиц

Объединение более двух таблиц не сложнее объединения двух. Главное правило таково — таблицы нужно объединять попарно, учитывая условия объединения. Это можно представить в виде отношений данных между первой таблицей, второй и третьей. Посмотрим на запрос:
select customers.name from customers,  orders,  order_iterns,  books where customers.customerid=orders.customerid and orders.orderid=order_iterns.orderid and order_iterns.isbn=books.isbn and books.title like '%Java%';
Обратите внимание, что были отслежены данные из четырех разных таблиц, а чтобы сделать это с помощью объединения по равенству, понадобились три разных условия объединения. Обычно каждой паре таблиц требуется одно условие объединения, таким образом, количество условий объединения на единицу меньше количества объединяемых таблиц. Это правило большого пальца может пригодиться при отладке запросов, которые работают неустойчиво. Проверьте свои условия объединения и убедитесь в том, что вы все время следовали намеченному пути, от того, что вы уже знаете — к тому,что нужно узнать.

Поиск несоответствующих строк

Другой распространенный тип соединения в MySQL — объединение по остатку. В предыдущих примерах отбирались только те строки, в которых наблюдалось соответствие между таблицами. Однако могут потребоваться и строки, в которых нет соответствия — например, нужно найти клиентов, которые не сделали ни одного заказа, или книги, которые никто не заказывал.
Самый простой вариант ответа на такой вопрос в MySQL — использование объединения по остатку, которое будет искать строки по указанному условию объединения двух таблиц. Если в указанной таблице нет подходящей строки, эта строка добавляется к результату, но с нулевым значением.
Взглянем на пример:
select customers.customerid,  customers.name,  orders.orderid from  customers  left  join  orders on customers.customerid=orders.customerid;
Данный запрос SQL использует объединение по остатку для таблиц Customers и Orders. Его синтаксис в отношении условий объединения несколько иной; условие объединения указывается в специальной конструкции ON оператора SQL.
Если необходимо найти исключительно тех клиентов, которые ничего не заказывали, этого можно достичь, проверив их на значение NULL в поле первичного ключа правой таблицы (в данном случае, orderid), поскольку строки с реальными значениями не могут иметь значение NULL:
select  customers.customerid, customers.name from  customers  left  join  orders using  (customerid)
where  orders.orderid  is  null;
Вероятно, вы обратили внимание на то, что в этом примере условие объединения обладает несколько другим синтаксисом. Объединение по остатку воспринимает как синтаксис ON, как было в первом примере, так и USING, как было во втором. Синтаксис USING не предполагает указания таблицы атрибута объединения, и по этой причине, если вы хотите пользоваться таким синтаксисом, столбцы в обеих таблицах должны называться одинаково.
2016.04.14 52

Войдите или Зарегистрируйтесь чтобы оставить комментарий

Комментарии


    Яндекс.Метрика Яндекс.Метрика