1 <sect1 id="zend.db.select">
3 <title>Zend_Db_Select</title>
5 <sect2 id="zend.db.select.introduction">
10 Объект Zend_Db_Select представляет SQL-оператор <code>SELECT</code>.
11 Класс имеет методы для добавления отдельных частей запроса. Вы
12 можете определять некоторые части запроса, используя методы PHP и
13 структуры данных, и класс формирует корректный синтаксис SQL.
14 После того, как построен запрос, можно выполнять его так же, как
15 если бы он был написан в виде строки.
19 В число достоинств Zend_Db_Select входит:
25 Объектно-ориентированные методы для "покусочного" построения
31 Не зависящая от типа БД абстракция некоторых частей
37 Автоматическое в большинстве случаев заключение в кавычки
38 идентификаторов метаданных для поддержки
39 идентификаторов, содержащих зарезервированные SQL слова и
45 Заключение в кавычки идентификаторов и значений для снижения
46 угрозы атак с использованием SQL-инъекций.
52 Использование Zend_Db_Select не обязательно. Для очень простых
53 запросов SELECT обычно проще указать SQL-запрос целиком в виде
54 строки и выполнить его, используя такие методы адаптера, как
55 <code>query()</code> или <code>fetchAll()</code>. Использование
56 Zend_Db_Select полезно, если нужно собрать запрос SELECT в процессе
57 или основываясь на условной логике.
62 <sect2 id="zend.db.select.creating">
64 <title>Создание объекта Select</title>
67 Вы можете создавать экземпляр объекта Zend_Db_Select, используя
68 метод <code>select()</code> объекта Zend_Db_Adapter_Abstract.
71 <example id="zend.db.select.creating.example-db">
73 <title>Пример использования метода select() адаптера БД</title>
75 <programlisting language="php"><![CDATA[
76 $db = Zend_Db::factory( ...опции... );
77 $select = $db->select();
84 Другой способ состоит в создании объекта Zend_Db_Select через
85 конструктор, при этом в качестве аргумента указывается адаптер БД.
88 <example id="zend.db.select.creating.example-new">
90 <title>Пример создания нового объекта Select</title>
92 <programlisting language="php"><![CDATA[
93 $db = Zend_Db::factory( ...опции... );
94 $select = new Zend_Db_Select($db);
102 <sect2 id="zend.db.select.building">
104 <title>Построение запросов Select</title>
107 При построении запроса вы можете добавлять по одному его
108 предложения. Предложение - это часть SQL-оператора, не
109 представляющая собой законченный оператор; например, предложение
110 WHERE. Для каждого предложения есть свой метод Zend_Db_Select.
113 <example id="zend.db.select.building.example">
115 <title>Пример использования методов для добавления предложений</title>
117 <programlisting language="php"><![CDATA[
118 // Создание объекта Zend_Db_Select
119 $select = $db->select();
121 // Добавление предложения FROM
122 $select->from( ...определение таблицы и столбцов... )
124 // Добавление предложения WHERE
125 $select->where( ...определение критериев поиска... )
127 // Добавление предложения ORDER BY
128 $select->order( ...определение критериев сортировки... );
135 Вы также можете использовать большинство методов объекта
136 Zend_Db_Select в так называемом fluent interface.
137 Fluent interface означает, что каждый метод возвращает ссылку на
138 тот объект, в котором он был вызван, поэтому вы можете вызывать
139 другой метод непосредственно за ним.
142 <example id="zend.db.select.building.example-fluent">
144 <title>Пример использования fluent interface</title>
146 <programlisting language="php"><![CDATA[
147 $select = $db->select()
148 ->from( ...определение таблицы и столбцов... )
149 ->where( ...определение критериев поиска... )
150 ->order( ...определение критериев сортировки... );
157 Этот пример демонстрирует применение fluent interface, но в любом
158 случае вы можете использовать стандартный подход. Часто
159 бывает необходимо использовать стандартный подход - например, когда
160 нужно выполнить некоторую логику до добавления предложения в запрос.
163 <sect3 id="zend.db.select.building.from">
165 <title>Добавление предложения FROM</title>
168 Указывайте таблицу для запроса, используя метод
169 <code>from()</code>. Вы можете задавать имя таблицы в виде
170 простой строки, Zend_Db_Select добавит идентификатор, заключив в
171 кавычки имя таблицы, поэтому вы можете использовать специальные
175 <example id="zend.db.select.building.from.example">
177 <title>Пример использования метода from()</title>
179 <programlisting language="php">
185 $select = $db->select()
186 ->from( 'products' );
193 Вы можете также задавать корреляционное (называемое также
194 "псевдонимом") имя таблицы. В этом случае вместо простой строки
195 используйте ассоциативный массив корреляционных имен и
196 действительных имен таблиц. В других предложениях SQL-запроса
197 используйте это корреляционное имя. Если в вашем запросе
198 объединяется более одной таблицы, то Zend_Db_Select генерирует
199 уникальные корреляционные имена, основанные на именах таблиц,
200 для всех таблиц, для которых не были заданы корреляционные
204 <example id="zend.db.select.building.from.example-cname">
206 <title>Пример задания корреляционного имени таблицы</title>
208 <programlisting language="php">
212 // FROM "products" AS p
214 $select = $db->select()
215 ->from( array('p' => 'products') );
221 Некоторые СУРБД поддерживают спецификатор схемы для таблицы. Вы
222 можете задавать имя таблицы в виде
223 "<code>имяСхемы.имяТаблицы</code>". Zend_Db_Select заключит в
224 кавычки все части по отдельности.
227 <example id="zend.db.select.building.from.example-schema">
229 <title>Пример задания имени схемы</title>
231 <programlisting language="php"><![CDATA[
234 // FROM "myschema"."products"
236 $select = $db->select()
237 ->from( 'myschema.products' );
241 $select = $db->select()
242 ->from('products', '*', 'myschema');
250 <sect3 id="zend.db.select.building.columns">
252 <title>Добавление колонок</title>
255 Во втором аргументе метода <code>from()</code> вы можете
256 задавать столбцы для выборки из соответствующей таблицы. Если вы
257 не укажете столбцы для выборки, то по умолчанию будет подставлен
258 метасимвол "<code>*</code>", означающий "все столбцы".
262 Вы можете перечислить столбцы в простом массиве строк или
263 в ассоциативном массиве псевдонимов столбцов и их имен. Если в
264 запросе нужен только один столбец, и к нему не нужен псевдоним,
265 то можно передать строку с его именем вместо массива.
269 Если вы передали пустой массив в качестве аргумента для
270 столбцов, то ни один столбец из соответствующей таблицы не будет
271 включен в результат выборки. См.
272 <link linkend="zend.db.select.building.join.example-no-columns">пример
273 кода</link> в разделе про метод <code>join()</code>.
277 Вы можете указать имя столбца как
278 "<code>корреляционноеИмя.имяСтолбца</code>". Zend_Db_Select
279 заключит в кавычки все части по отдельности. Если вы не укажете
280 корреляционное имя для столбца, то используется корреляционное
281 имя таблицы, указанной в текущем вызове метода
285 <example id="zend.db.select.building.columns.example">
287 <title>Пример указания столбцов</title>
289 <programlisting language="php"><![CDATA[
291 // SELECT p."product_id", p."product_name"
292 // FROM "products" AS p
294 $select = $db->select()
295 ->from(array('p' => 'products'),
296 array('product_id', 'product_name'));
298 // Строит тот же запрос с указанием корреляционных имен:
299 // SELECT p."product_id", p."product_name"
300 // FROM "products" AS p
302 $select = $db->select()
303 ->from(array('p' => 'products'),
304 array('p.product_id', 'p.product_name'));
306 // Строит тот же запрос с псевдонимом для одного столбца:
307 // SELECT p."product_id" AS prodno, p."product_name"
308 // FROM "products" AS p
310 $select = $db->select()
311 ->from(array('p' => 'products'),
312 array('prodno' => 'product_id', 'product_name'));
320 <sect3 id="zend.db.select.building.columns-expr">
322 <title>Добавление столбцов выражений</title>
325 Столбцы в SQL-запросах иногда представляют собой выражения, а не
326 просто столбцы из таблицы. Выражения не должны иметь
327 корреляционные имена и заключаться в кавычки. Если строка,
328 обозначающая столбец запроса, содержит скобки, то Zend_Db_Select
329 распознает ее как выражение.
333 Вы можете также явно создавать объект типа Zend_Db_Expr для
334 того, чтобы предотвратить ошибочное распознавание строки как
335 имени столбца. Zend_Db_Expr - мини-класс, содержащий
336 только строку. Zend_Db_Select распознает объекты типа
337 Zend_Db_Expr и преобразует их обратно в строку, но без таких
338 действий, как заключение в кавычки и добавление корелляционных
344 Использование Zend_Db_Expr не обязательно, если ваше
345 выражение содержит скобки. Zend_Db_Select распознает
346 выражение по скобкам и оперирует строкой как выражением,
347 пропуская такие действия, как заключение в кавычки и
348 добавление корреляционных имен.
352 <example id="zend.db.select.building.columns-expr.example">
354 <title>Пример указания столбцов, содержащих выражения</title>
356 <programlisting language="php"><![CDATA[
358 // SELECT p."product_id", LOWER(product_name)
359 // FROM "products" AS p
360 // Выражение со скобками неявно преобразуется в Zend_Db_Expr.
362 $select = $db->select()
363 ->from(array('p' => 'products'),
364 array('product_id', 'LOWER(product_name)'));
367 // SELECT p."product_id", (p.cost * 1.08) AS cost_plus_tax
368 // FROM "products" AS p
370 $select = $db->select()
371 ->from(array('p' => 'products'),
373 'cost_plus_tax' => '(p.cost * 1.08)')
376 // Построение того же запроса с явным использованием Zend_Db_Expr:
377 // SELECT p."product_id", p.cost * 1.08 AS cost_plus_tax
378 // FROM "products" AS p
380 $select = $db->select()
381 ->from(array('p' => 'products'),
384 new Zend_Db_Expr('p.cost * 1.08'))
392 В примерах выше Zend_Db_Select не модифицирует строку для
393 добавления корреляционных имен или заключения идентификаторов в
394 кавычки. Если эти изменения необходимы для исключения
395 неоднозначности, то вы должны произвести их в строке вручную.
399 Если имена столбцов являются ключевыми словами SQL или содержат
400 специальные символы, то следует использовать метод адаптера
401 <code>quoteIdentifier()</code> и включать результат в строку.
402 Метод <code>quoteIdentifier()</code> использует заключение в
403 кавычки для ограничения идентификатора, тем самым обозначается,
404 что это идентификатор таблицы или столбца, а не другая часть
409 Ваш код будет более независимым от типа БД, если вы будете
410 использовать метод <code>quoteIdentifier()</code> вместо
411 непосредственного добавления кавычек в строке, поскольку
412 некоторые БД используют нестандартные символы вместо кавычек.
413 Метод <code>quoteIdentifier()</code>
414 использует нужные символы, основываясь на типе
415 адаптера. <code>quoteIdentifier()</code> также экранирует
416 символы кавычек в самом идентификаторе.
419 <example id="zend.db.select.building.columns-quoteid.example">
421 <title>Пример заключения в кавычки столбцов в выражении</title>
423 <programlisting language="php"><![CDATA[
424 // Строится следующий запрос, при этом имя столбца "from" в выражении
425 // заключается в кавычки:
426 // SELECT p."from" + 10 AS origin
427 // FROM "products" AS p
429 $select = $db->select()
430 ->from(array('p' => 'products'),
432 '(p.' . $db->quoteIdentifier('from') . ' + 10)')
441 <sect3 id="zend.db.select.building.columns-atomic">
443 <title>Добавление столбцов в существующую таблицу FROM или JOIN</title>
446 Может потребоваться добавить столбцы в таблицу FROM или JOIN
447 после того, как были вызваны соответствующие методы. Метод
448 <code>columns()</code> позволяет добавлять определенные столбцы
449 в любой момент до того, как будет выполнен запрос. Вы можете
450 передавать столбцы в виде строки, объекта
451 <code>Zend_Db_Expr</code> или массива этих элементов. Второй
452 аргумент этого метода может быть опущен, это значит, что столбцы
453 должны быть добавлены в таблицу FROM, иначе должно
454 использоваться существующее корреляционное имя.
457 <example id="zend.db.select.building.columns-atomic.example">
459 <title>Пример добавления столбцов через метод <code>columns()</code></title>
461 <programlisting language="php"><![CDATA[
462 // Строится следующий запрос:
463 // SELECT p."product_id", p."product_name"
464 // FROM "products" AS p
466 $select = $db->select()
467 ->from(array('p' => 'products'), 'product_id')
468 ->columns('product_name');
470 // Строится тот же запрос с указанием корреляционных имен:
471 // SELECT p."product_id", p."product_name"
472 // FROM "products" AS p
474 $select = $db->select()
475 ->from(array('p' => 'products'), 'p.product_id')
476 ->columns('product_name', 'p');
477 // Можно также писать: columns('p.product_name')]]>
484 <sect3 id="zend.db.select.building.join">
486 <title>Добавление в запрос другой таблицы c помощью JOIN</title>
489 Многие полезные запросы используют <code>JOIN</code> для
490 объединения строк из разных таблиц. Вы можете добавлять таблицы
491 в запрос, используя метод <code>join()</code> объекта
492 Zend_Db_Select. Использование этого метода похоже на
493 использование <code>from()</code> за тем исключением, что в
494 большинстве случаев вам нужно будет также указать условие
498 <example id="zend.db.select.building.join.example">
500 <title>Пример использования метода join()</title>
502 <programlisting language="php"><![CDATA[
504 // SELECT p."product_id", p."product_name", l.*
505 // FROM "products" AS p JOIN "line_items" AS l
506 // ON p.product_id = l.product_id
508 $select = $db->select()
509 ->from(array('p' => 'products'),
510 array('product_id', 'product_name'))
511 ->join(array('l' => 'line_items'),
512 'p.product_id = l.product_id');
518 Второй аргумент метода <code>join()</code> является строкой,
519 содержащей условие объединения. Это выражение объявляет условие,
520 при выполнении которого строки в одной таблице объединяются со
521 сроками в другой таблице. Вы можете использовать корреляционные
522 имена в этом выражении.
527 К выражению, указанному вами как условие объединения, не
528 применяется автоматическое заключение в кавычки. Если нужно
529 заключить в кавычки имена столбцов, то используйте
530 <code>quoteIdentifier()</code> при формировании строки
536 Третий аргумент метода <code>join()</code> - массив имен
537 столбцов, как и в методе <code>from()</code>. По умолчанию
538 используется "<code>*</code>" вместо столбцов,
539 поддерживаются корреляционные имена, выражения и Zend_Db_Expr -
540 так же, как и в случае массива столбцов для метода
545 Если из таблицы не нужно выбирать столбцы, то используйте пустой
546 массив вместо перечисления столбцов. Это работает и для метода
547 <code>from()</code>, но обычно требуется извлечь часть столбцов
548 из основной таблицы в запросе, при этом может не требоваться
549 получение столбцов из присоединяемой таблицы.
552 <example id="zend.db.select.building.join.example-no-columns">
554 <title>Пример извлечения без столбцов</title>
556 <programlisting language="php"><![CDATA[
558 // SELECT p."product_id", p."product_name"
559 // FROM "products" AS p JOIN "line_items" AS l
560 // ON p.product_id = l.product_id
562 $select = $db->select()
563 ->from(array('p' => 'products'),
564 array('product_id', 'product_name'))
565 ->join(array('l' => 'line_items'),
566 'p.product_id = l.product_id',
567 array() ); // empty list of columns
572 Обратите внимание на пустой <code>array()</code> в примере
573 выше вместо списка столбцов из присоединяемой таблицы.
579 SQL имеет несколько типов объединений. Ниже приведен список
580 методов для поддержки различных типов объединений в
587 <command>INNER JOIN</command>, методы
588 <code>join(table, join, [columns])</code>
589 и <code>joinInner(table, join, [columns])</code>.
592 Возможно, наиболее часто используемый тип объединения.
593 Строки из каждой таблицы сравниваются с
594 использованием условия сравнения. Результат включает в
595 себя только те строки, которые удовлетворяют условию
596 объединения. Результат может быть пустым, если ни одна
597 строка не удовлетворяет этому условию.
600 Все СУРБД поддерживают этот тип объединения.
605 <command>LEFT JOIN</command>, метод <code>joinLeft(table, condition, [columns])</code>.
608 В результат входят все строки из таблицы слева и все
609 соответствующие строки из таблицы справа. Если нет
610 соответствующих строк из таблицы справа, то
611 соответствующие столбцы в результате заполняются NULL.
614 Все СУРБД поддерживают этот тип объединения.
619 <command>RIGHT JOIN</command>, метод <code>joinRight(table, condition, [columns])</code>.
622 Правое внешнее объединение дополняет левое внешнее
623 объединение. В результат входят все строки из таблицы
624 справа и все соответствующие строки из таблицы слева.
625 Если нет соответствующих строк из таблицы слева, то
626 соответствующие столбцы в результате заполняются NULL.
629 Некоторые СУРБД не поддерживают этот тип объединения,
630 но, как правило, любое правое объединение может быть
631 заменено на левое посредством изменения порядка таблиц
637 <command>FULL JOIN</command>, метод
638 <code>joinFull(table, condition, [columns])</code>.
641 Полное внешнее объединение является как бы комбинацией
642 левого и правого объединений. Все строки из обоих таблиц
643 входят в результат, при этом объединяются друг с другом
644 в одну строку результата, если соответствуют условию
645 объединения, иначе объединяются с NULL вместо значений
646 столбцов из другой таблицы.
649 Некоторые СУРБД не поддерживают этот тип объединения.
654 <command>CROSS JOIN</command>, метод
655 <code>joinCross(table, [columns])</code>.
658 Перекрестное объединение является декартовым
659 произведением. Каждая строка в первой таблице
660 объединяется с со всеми строками во второй таблице.
661 Таким образом, количество строк в результате будет равно
662 произведению числа строк в обоих таблицах. Вы можете
663 фильтровать результат, используя условие в предложении
664 WHERE, в этом случае перекрестное объединение подобно
665 старому синтаксису объединений в SQL-89.
668 Метод <code>joinCross()</code> не имеет параметров для
669 определения условий объединения. Некоторые СУРБД не
670 поддерживают этот тип объединения.
675 <command>NATURAL JOIN</command>, метод
676 <code>joinNatural(table, [columns])</code>.
679 Естественное объединение сравнивает столбцы, имеющие
680 одинаковые имена в обоих таблицах. Проверка производится
681 на равенство; проверка на неравенство не является
682 естественным объединением.
683 Данным API поддерживаются только внутренние
684 естественные объединения, даже если SQL поддерживает
685 внешние естественные объединения.
688 Метод <code>joinNatural()</code> не имеет параметров для
689 определения условий объединения.
695 В дополнение к этим методам объединения вы можете упростить свои
696 запросы, используя методы JoinUsing. Вместо предоставления
697 полного условия объединения вы можете просто передавать имя
698 столбца, по которому производится объединение, и Zend_Db_Select
699 допишет условие объединения за вас.
702 <example id="zend.db.select.building.joinusing.example">
704 <title>Пример использования метода joinUsing()</title>
706 <programlisting language="php"><![CDATA[
711 // ON "table1".column1 = "table2".column1
712 // WHERE column2 = 'foo'
714 $select = $db->select()
716 ->joinUsing('table2', 'column1')
717 ->where('column2 = ?', 'foo');]]>
723 Каждый метод объединения из перечисленных выше имеет соответствующий ему метод JoinUsing.
729 <code>joinUsing(table, join, [columns])</code> и
730 <code>joinInnerUsing(table, join, [columns])</code>
736 <code>joinLeftUsing(table, join, [columns])</code>
742 <code>joinRightUsing(table, join, [columns])</code>
748 <code>joinFullUsing(table, join, [columns])</code>
755 <sect3 id="zend.db.select.building.where">
757 <title>Добавление предложения WHERE</title>
760 Вы можете задавать условия для ограничения строк в результате
761 выборки, используя метод <code>where()</code>. Первым аргументом
762 этого метода является SQL-выражение, которое используется в
763 предложении <code>WHERE</code> в данном запросе.
766 <example id="zend.db.select.building.where.example">
768 <title>Пример использования метода where()</title>
770 <programlisting language="php"><![CDATA[
772 // SELECT product_id, product_name, price
774 // WHERE price > 100.00
776 $select = $db->select()
778 array('product_id', 'product_name', 'price'))
779 ->where('price > 100.00');]]>
786 К выражениям для методов <code>where()</code> или
787 <code>orWhere()</code> не применяется автоматическое
788 заключение в кавычки. Если необходимо, чтобы имена столбцов
789 были заключены в кавычки, то используйте метод
790 <code>quoteIdentifier()</code> при формировании строки
796 Второй аргумент метода <code>where()</code> является
797 опциональным. Это значение подставляется в выражение.
798 Zend_Db_Select заключает это значение в кавычки и подставляет
799 вместо знака вопроса ("<code>?</code>") в выражении.
803 Этот метод принимает только один параметр. Если в выражение
804 подставляется несколько значений, то нужно сформировать строку
805 вручную, вставляя переменные и заключая их в кавычки
809 <example id="zend.db.select.building.where.example-param">
811 <title>Пример параметра в методе where()</title>
813 <programlisting language="php"><![CDATA[
815 // SELECT product_id, product_name, price
817 // WHERE (price > 100.00)
821 $select = $db->select()
823 array('product_id', 'product_name', 'price'))
824 ->where('price > ?', $minimumPrice);
831 Вы можете вызывать метод <code>where()</code> несколько раз на
832 одном и том же объекте Zend_Db_Select. Результирующий запрос
833 объединяет в себе все термы с добавлением <code>AND</code>
837 <example id="zend.db.select.building.where.example-and">
839 <title>Пример нескольких вызовов метода where()</title>
841 <programlisting language="php"><![CDATA[
843 // SELECT product_id, product_name, price
845 // WHERE (price > 100.00)
846 // AND (price < 500.00)
851 $select = $db->select()
853 array('product_id', 'product_name', 'price'))
854 ->where('price > ?', $minimumPrice)
855 ->where('price < ?', $maximumPrice);
862 Если вам нужно объединить термы с использованием
863 <code>OR</code>, то используйте метод <code>orWhere()</code>.
864 Этот метод используется так же, как и метод
865 <code>where()</code>, за тем исключением, что определенный в
866 этом вызове терм добавляется вместе с <code>OR</code> вместо
870 <example id="zend.db.select.building.where.example-or">
872 <title>Пример использования метода orWhere()</title>
874 <programlisting language="php"><![CDATA[
876 // SELECT product_id, product_name, price
878 // WHERE (price < 100.00)
879 // OR (price > 500.00)
884 $select = $db->select()
886 array('product_id', 'product_name', 'price'))
887 ->where('price < ?', $minimumPrice)
888 ->orWhere('price > ?', $maximumPrice);
895 Zend_Db_Select автоматически заключает в скобки все выражения,
896 которые вы добавляете через методы <code>where()</code> или
897 <code>orWhere()</code>. Это позволяет быть уверенным в том, что
898 приоритет булевых операторов не приведет к другому результату
902 <example id="zend.db.select.building.where.example-parens">
904 <title>Пример заключения булевых выражений в скобки</title>
906 <programlisting language="php"><![CDATA[
908 // SELECT product_id, product_name, price
910 // WHERE (price < 100.00 OR price > 500.00)
911 // AND (product_name = 'Apple')
917 $select = $db->select()
919 array('product_id', 'product_name', 'price'))
920 ->where("price < $minimumPrice OR price > $maximumPrice")
921 ->where('product_name = ?', $prod);
928 В примере выше результаты могут отличаться от тех, что
929 получаются без скобок, потому что <code>AND</code> имеет больший
930 приоритет, чем <code>OR</code>. Zend_Db_Select добавляет скобки,
931 Таким образом, результатом является то, что каждое выражение,
932 добавленное в успешных вызовах <code>where()</code> более
933 связанно, чем <code>AND</code>, объединяющее эти выражения.
938 <sect3 id="zend.db.select.building.group">
940 <title>Добавление предложения GROUP BY</title>
943 В языке SQL выражение <code>GROUP BY</code> позволяет ограничить
944 количество строк в результатах запроса до одной стоки на каждое
945 уникальное значение в столбцах, перечисленных в предложении
946 <code>GROUP BY</code>.
950 В Zend_Db_Select вы можете задавать столбцы, используемые для
951 определения групп строк, через метод <code>group()</code>.
952 Аргументом этого метода является столбец или массив столбцов для
953 подстановки в предложение <code>GROUP BY</code>.
956 <example id="zend.db.select.building.group.example">
958 <title>Пример использования метода group()</title>
960 <programlisting language="php"><![CDATA[
962 // SELECT p."product_id", COUNT(*) AS line_items_per_product
963 // FROM "products" AS p JOIN "line_items" AS l
964 // ON p.product_id = l.product_id
965 // GROUP BY p.product_id
967 $select = $db->select()
968 ->from(array('p' => 'products'),
970 ->join(array('l' => 'line_items'),
971 'p.product_id = l.product_id',
972 array('line_items_per_product' => 'COUNT(*)'))
973 ->group('p.product_id');
980 Как и для массива столбцов в методе <code>from()</code>, вы
981 можете использовать корреляционные имена в именах столбцов,
982 столбцы заключаются в кавычки в качестве идентификаторов, если
983 строка не содержит скобок или является объектом типа
989 <sect3 id="zend.db.select.building.having">
991 <title>Добавление предложения HAVING</title>
994 В SQL предложение <code>HAVING</code> применяет условие
995 ограничения к группам строк. Это подобно тому, как предложение
996 <code>WHERE</code> применяет условие ограничения к строкам.
997 Но эти предложения не являются идентичными, поскольку условия
998 <code>WHERE</code> применяются до группировки, в то время как
999 условия <code>HAVING</code> применяется после группировки.
1003 В Zend_Db_Select вы можете определять условия ограничения
1004 групп через метод <code>having()</code>. Его использование
1005 аналогично использованию метода <code>where()</code>. Первый
1006 аргумент является строкой, содержащей SQL-выражение.
1007 Опциональный второй аргумент - значение, которое используется
1008 для подстановки вместо метки заполнения в SQL-выражении.
1009 Выражения, переданные в нескольких вызовах метода
1010 <code>having()</code>, объединяются через булевый оператор
1011 <code>AND</code> или через булевый оператор
1012 <code>OR</code>, если вы используете метод
1013 <code>orHaving()</code>.
1016 <example id="zend.db.select.building.having.example">
1018 <title>Пример использования метода having()</title>
1020 <programlisting language="php"><![CDATA[
1022 // SELECT p."product_id", COUNT(*) AS line_items_per_product
1023 // FROM "products" AS p JOIN "line_items" AS l
1024 // ON p.product_id = l.product_id
1025 // GROUP BY p.product_id
1026 // HAVING line_items_per_product > 10
1028 $select = $db->select()
1029 ->from(array('p' => 'products'),
1030 array('product_id'))
1031 ->join(array('l' => 'line_items'),
1032 'p.product_id = l.product_id',
1033 array('line_items_per_product' => 'COUNT(*)'))
1034 ->group('p.product_id')
1035 ->having('line_items_per_product > 10');
1043 К выражениям, переданным через методы <code>having()</code>
1044 или <code>orHaving()</code>, не применяется автоматическое
1045 заключение в кавычки. Если у вас есть имена столбцов,
1046 которые требуется заключить в кавычки, то используйте
1047 <code>quoteIdentifier()</code> при формировании строки
1054 <sect3 id="zend.db.select.building.order">
1056 <title>Добавление предложения ORDER BY</title>
1059 В SQL предложение <code>ORDER BY</code> задает один или более
1060 столбцов (или выражений), по которым сортируется результат
1061 запроса. Если перечислено несколько столбцов, то вторичные
1062 столбцы используются для принятия решения в ситуации "ничьи":
1063 если первичные столбцы содержат идентичные значения, то порядок
1064 сортировки определяется через вторичные столбцы. По умолчанию
1065 сортировка производится от меньших значений к большим. Вы можете
1066 также производить для данного столбца сортировку от больших
1067 значений к меньшим, указав ключевое слово <code>DESC</code>
1068 после этого столбца.
1072 В Zend_Db_Select вы можете использовать метод
1073 <code>order()</code> для определения столбца или массива
1074 столбцов, по которым производится сортировка. Каждый элемент
1075 массива является строкой с именем столбца, опционально строка
1076 может содержать ключевое слово <code>ASC</code> или
1077 <code>DESC</code> после имени столбца и отделенное от него
1082 Как и в случае методов <code>from()</code> и
1083 <code>group()</code>, имена столбцов заключаются в кавычки в
1084 качестве идентификаторов, если они не содержат скобки и не
1085 являются объектами Zend_Db_Expr.
1088 <example id="zend.db.select.building.order.example">
1090 <title>Пример использования метода order()</title>
1092 <programlisting language="php"><![CDATA[
1094 // SELECT p."product_id", COUNT(*) AS line_items_per_product
1095 // FROM "products" AS p JOIN "line_items" AS l
1096 // ON p.product_id = l.product_id
1097 // GROUP BY p.product_id
1098 // ORDER BY "line_items_per_product" DESC, "product_id"
1100 $select = $db->select()
1101 ->from(array('p' => 'products'),
1102 array('product_id'))
1103 ->join(array('l' => 'line_items'),
1104 'p.product_id = l.product_id',
1105 array('line_items_per_product' => 'COUNT(*)'))
1106 ->group('p.product_id')
1107 ->order(array('line_items_per_product DESC',
1116 <sect3 id="zend.db.select.building.limit">
1118 <title>Добавление предложения LIMIT</title>
1121 Некоторые СУРБД расширяют язык SQL предложением, известным как
1122 предложение <code>LIMIT</code>. Это предложение ограничивает
1123 количество строк в результате запроса до заданного вами
1124 количества. Вы можете также задать количество пропускаемых до
1125 начала вывода строк. Эта возможность облегчает выборку
1126 подмножества строк результата - например, для постраничного
1127 вывода результатов запроса.
1131 В Zend_Db_Select вы можете использовать метод
1132 <code>limit()</code> для задания количества строк в выборке и
1133 количества пропускаемых строк. Первым аргументом этого метода
1134 является желаемое количество строк в результате запроса. Вторым
1135 аргументом - количество пропускаемых строк
1138 <example id="zend.db.select.building.limit.example">
1140 <title>Пример использования метода limit()</title>
1142 <programlisting language="php"><![CDATA[
1144 // SELECT p."product_id", p."product_name"
1145 // FROM "products" AS p
1148 $select = $db->select()
1149 ->from(array('p' => 'products'),
1150 array('product_id', 'product_name'))
1159 Ситаксис <code>LIMIT</code> поддерживается не всеми СУРБД.
1160 Некоторые СУРБД используют другой синтаксис для поддержки
1161 аналогичной функциональности. Каждый класс
1162 Zend_Db_Adapter_Abstract включает в себя метод для генерации
1163 SQL, присущего данной СУРБД.
1168 Используйте метод <code>limitPage()</code> в качестве
1169 альтернативного способа указания количества строк и смещения.
1170 Этот метод позволяет ограничить набор возвращаемых результатов
1171 подмножеством фиксированной длины, который является одним из
1172 последовательности подмножеств, составляющих весь набор
1173 результатов запроса.
1174 Другими словами, вы указываете длину "страницы" результатов в
1175 строках и порядковый номер страницы для извлечения. Номер
1176 страницы является первым аргументом в методе
1177 <code>limitPage()</code>, а длина страницы - вторым. Оба
1178 аргумента являются обязательными и не имеют значений по
1182 <example id="zend.db.select.building.limit.example2">
1184 <title>Пример использования метода limitPage()</title>
1186 <programlisting language="php"><![CDATA[
1188 // SELECT p."product_id", p."product_name"
1189 // FROM "products" AS p
1192 $select = $db->select()
1193 ->from(array('p' => 'products'),
1194 array('product_id', 'product_name'))
1203 <sect3 id="zend.db.select.building.distinct">
1205 <title>Добавление модификатора DISTINCT</title>
1208 Метод <code>distinct()</code> дает возможность добавлять
1209 ключевое слово <code>DISTINCT</code> в ваш запрос.
1212 <example id="zend.db.select.building.distinct.example">
1214 <title>Пример использования метода distinct()</title>
1216 <programlisting language="php"><![CDATA[
1218 // SELECT DISTINCT p."product_name"
1219 // FROM "products" AS p
1221 $select = $db->select()
1223 ->from(array('p' => 'products'), 'product_name');
1231 <sect3 id="zend.db.select.building.for-update">
1233 <title>Добавление модификатора FOR UPDATE</title>
1236 Метод <code>forUpdate()</code> дает возможность добавлять
1237 модификатор <code>FOR UPDATE</code> в ваш запрос.
1240 <example id="zend.db.select.building.for-update.example">
1242 <title>Пример использования метода forUpdate()</title>
1244 <programlisting language="php"><![CDATA[
1246 // SELECT FOR UPDATE p.*
1247 // FROM "products" AS p
1249 $select = $db->select()
1251 ->from(array('p' => 'products'));
1261 <sect2 id="zend.db.select.execute">
1263 <title>Произведение запросов на выборку</title>
1266 Этот раздел объясняет, как производить запрос, представленный
1267 объектом Zend_Db_Select.
1270 <sect3 id="zend.db.select.execute.query-adapter">
1272 <title>Произведение запросов на выборку из адаптера БД</title>
1275 Вы можете производить запрос, представленный объектом
1276 Zend_Db_Select, посредством передачи его в качестве первого
1277 аргумента методу <code>query()</code> объекта
1278 Zend_Db_Adapter_Abstract. Используйте объекты Zend_Db_Select
1279 вместо строк запроса.
1283 Метод <code>query()</code> возвращает объект Zend_Db_Statement
1284 или PDOStatement, в зависимости от типа адаптера.
1287 <example id="zend.db.select.execute.query-adapter.example">
1289 <title>Пример использования метода query() адаптера БД</title>
1291 <programlisting language="php"><![CDATA[
1292 $select = $db->select()
1295 $stmt = $db->query($select);
1296 $result = $stmt->fetchAll();
1304 <sect3 id="zend.db.select.execute.query-select">
1306 <title>Произведение запросов на выборку через объект Select</title>
1309 Вместо метода <code>query()</code> объекта адаптера можно
1310 использовать метод <code>query()</code> объекта Zend_Db_Select.
1311 Оба метода возвращают объект типа Zend_Db_Statement или
1312 PDOStatement, в зависимости от типа адаптера.
1315 <example id="zend.db.select.execute.query-select.example">
1317 <title>Пример использования метода query() объекта Select</title>
1319 <programlisting language="php"><![CDATA[
1320 $select = $db->select()
1323 $stmt = $select->query();
1324 $result = $stmt->fetchAll();
1332 <sect3 id="zend.db.select.execute.tostring">
1334 <title>Преобразование объекта Select в SQL-строку</title>
1337 Если нужно получить доступ к строковому представлению
1338 SQL-запроса, соответствующего данному объекту Zend_Db_Select, то
1339 используйте метод <code>__toString()</code>.
1342 <example id="zend.db.select.execute.tostring.example">
1344 <title>Пример использования метода __toString()</title>
1346 <programlisting language="php"><![CDATA[
1347 $select = $db->select()
1350 $sql = $select->__toString();
1353 // Выводится будет строка:
1354 // SELECT * FROM "products"
1364 <sect2 id="zend.db.select.other">
1366 <title>Другие методы</title>
1369 Этот раздел описывает другие методы класса Zend_Db_Select, которые
1370 не были охвачены ранее: <code>getPart()</code> и
1371 <code>reset()</code>.
1374 <sect3 id="zend.db.select.other.get-part">
1376 <title>Получение частей объекта Select</title>
1379 Метод <code>getPart()</code> возвращает представление
1380 определенной части вашего запроса. Например, вы можете
1381 использовать этот метод для получения строки выражения для
1382 предложения <code>WHERE</code>, массива столбцов, перечисленных
1383 для получения выборки по ним, значений количества и смещения для
1384 предложения <code>LIMIT</code>.
1388 Возвращаемое значение не является строкой, содержащей фрагмент
1389 запроса SQL. Возвращаемое значение является внутренним
1390 представлением в объекте, обычно это массив, содержащий значения
1391 и выражения. Каждая часть запроса имеет различную структуру.
1395 Единственным аргументом метода <code>getPart()</code> является
1396 строка, идентифицирующая часть запроса, которую требуется
1397 вернуть. Например, строка <code>'from'</code> соответствует той
1398 части запроса, которая хранит информацию о таблицах в
1399 предложении <code>FROM</code>, включая присоединяемые таблицы.
1403 Zend_Db_Select определяет константы, которые вы можете
1404 использовать для частей SQL-запроса. Вы можете использовать эти
1405 константы или литеральные строки.
1408 <table id="zend.db.select.other.get-part.table">
1409 <title>Константы, используемые методами getPart() и reset()</title>
1413 <entry>Константа</entry>
1414 <entry>Строковое значение</entry>
1419 <entry><code>Zend_Db_Select::DISTINCT</code></entry>
1420 <entry><code>'distinct'</code></entry>
1423 <entry><code>Zend_Db_Select::FOR_UPDATE</code></entry>
1424 <entry><code>'forupdate'</code></entry>
1427 <entry><code>Zend_Db_Select::COLUMNS</code></entry>
1428 <entry><code>'columns'</code></entry>
1431 <entry><code>Zend_Db_Select::FROM</code></entry>
1432 <entry><code>'from'</code></entry>
1435 <entry><code>Zend_Db_Select::WHERE</code></entry>
1436 <entry><code>'where'</code></entry>
1439 <entry><code>Zend_Db_Select::GROUP</code></entry>
1440 <entry><code>'group'</code></entry>
1443 <entry><code>Zend_Db_Select::HAVING</code></entry>
1444 <entry><code>'having'</code></entry>
1447 <entry><code>Zend_Db_Select::ORDER</code></entry>
1448 <entry><code>'order'</code></entry>
1451 <entry><code>Zend_Db_Select::LIMIT_COUNT</code></entry>
1452 <entry><code>'limitcount'</code></entry>
1455 <entry><code>Zend_Db_Select::LIMIT_OFFSET</code></entry>
1456 <entry><code>'limitoffset'</code></entry>
1462 <example id="zend.db.select.other.get-part.example">
1464 <title>Пример использования метода getPart()</title>
1466 <programlisting language="php"><![CDATA[
1467 $select = $db->select()
1469 ->order('product_id');
1471 // Вы можете использовать строковой литерал для указания части запроса
1472 $orderData = $select->getPart( 'order' );
1474 // Можно использовать константу для указания той же части
1475 $orderData = $select->getPart( Zend_Db_Select::ORDER );
1477 // Возвращаемое значение может быть массивом, а не строкой
1478 // Каждая часть имет свою структуру
1479 print_r( $orderData );
1487 <sect3 id="zend.db.select.other.reset">
1489 <title>Сброс частей запроса в объекте Select</title>
1492 Через метод <code>reset()</code> вы можете очистить
1493 определенную часть SQL-запроса или все части запроса, если
1498 Единственный аргумент метода является опциональным. Вы можете
1499 указать часть запроса для очистки, используя те же строки,
1500 которые используются для метода <code>getPart()</code>. Та часть
1501 запроса, которую вы указали, сбрасывается в состояние по
1506 Если вы опустите этот параметр, то <code>reset()</code>
1507 сбрасывает все части запроса в состояние по умолчанию. Это
1508 делает объект Zend_Db_Select эквивалентным новому объекту - так
1509 же, как если бы вы его только что инстанцировали его.
1512 <example id="zend.db.select.other.reset.example">
1514 <title>Пример использования метода reset()</title>
1516 <programlisting language="php"><![CDATA[
1519 // FROM "products" AS p
1520 // ORDER BY "product_name"
1522 $select = $db->select()
1523 ->from(array('p' => 'products')
1524 ->order('product_name');
1526 // Changed requirement, instead order by a different columns:
1527 // Теперь нужна сортировка по другому столбцу:
1529 // FROM "products" AS p
1530 // ORDER BY "product_id"
1532 // Очищаем соответствующую часть, теперь можно переопределить ее
1533 $select->reset( Zend_Db_Select::ORDER );
1535 // Задаем другой столбец
1536 $select->order('product_id');
1538 // Очищаем все части запроса
1551 vim:se ts=4 sw=4 et: