Использование оператора UNION несколько раз

ALEZ

Новичок
Использование оператора UNION несколько раз

Добрый вечер.

Возникла потребность выполнить запрос следующей структуры:

PHP:
(
  (SELECT) UNION (SELECT) UNION (SELECT) ORDER BY
)
  UNION
(
  SELECT
)
Можно ли использовать UNION таким образом? У меня почему-то не получается, Mysql указывает на ошибку в начале второго SELECT первой группы запросов.
 

FractalizeR

Новичок
Какую именно ошибку и как именно выглядит ваш запрос?
Много UNION не запрещено использовать:
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 вернет три ряда по единице.

Кстати, скобки зачем у вас стоят?
 

ALEZ

Новичок
FractalizeR
MySQL возвращает синтаксическую ошибку в сроке, начиная с первого UNION, который встречается в запросе. Если дословно, то:
PHP:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL 
server version for the right syntax to use near 'UNION  ( SELECT `FUN_partymixes` . `id` , 
`FUN_partymixes` . `type` , `FUN_party' at line 1
Скобки я ставлю потому, что так написано в примерах книги "Mysql. Учебное пособие" (Веллинг, Томсон).

Много UNION использовать можно, первая группа запросов выполняется отлично. Интересует именно возможность использования UNION в иерархическом порядке.

Стоит ли мне показать весь запрос? Это поможет выявить проблему?
 

kode

never knows best
Автор оригинала: ALEZ
FractalizeR
MySQL возвращает синтаксическую ошибку в сроке, начиная с первого UNION, который встречается в запросе. Если дословно, то:
PHP:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL 
server version for the right syntax to use near 'UNION  ( SELECT `FUN_partymixes` . `id` , 
`FUN_partymixes` . `type` , `FUN_party' at line 1
Скобки я ставлю потому, что так написано в примерах книги "Mysql. Учебное пособие" (Веллинг, Томсон).

Много UNION использовать можно, первая группа запросов выполняется отлично. Интересует именно возможность использования UNION в иерархическом порядке.

Стоит ли мне показать весь запрос? Это поможет выявить проблему?
Вы можете привести весь SQL-запрос?
 

ALEZ

Новичок
Да, конечно. Вот запрос:

PHP:
(
   (SELECT `FUN_fireworks`.`id`, `FUN_fireworks`.`type`, `FUN_fireworks`.`appellation`, `FUN_fireworks`.`name`, `FUN_fireworks`.`working_time`, `FUN_fireworks`.`lifting_height`, `FUN_fireworks`.`shell_number`, `FUN_fireworks`.`description`, `FUN_fireworks`.`price`, `FUN_fireworks`.`weight` as `weight`, `FUN_images`.`link` as `photo` FROM `FUN_fireworks`, `FUN_images` WHERE `FUN_fireworks`.`display` = 'yes' AND `FUN_images`.`type` = 'fireworks' AND `FUN_images`.`id_owner` = `FUN_fireworks`.`id` AND `FUN_images`.`size` = '120')
      UNION
   (SELECT `FUN_partymixes`.`id`, `FUN_partymixes`.`type`, `FUN_partymixes`.`appellation`, `FUN_partymixes`.`name`, NULL as `working_time`, NULL as `lifting_height`, NULL as `shell_number`, `FUN_partymixes`.`description`, `FUN_partymixes`.`price`, `FUN_partymixes`.`weight` as `weight`, `FUN_images`.`link` as `photo` FROM `FUN_partymixes`, `FUN_images` WHERE `FUN_partymixes`.`display` = 'yes' AND `FUN_images`.`type` = 'partymixes' AND `FUN_images`.`id_owner` = `FUN_partymixes`.`id` AND `FUN_images`.`size` = '120')
      UNION
   (SELECT `FUN_ballons`.`id`, `FUN_ballons`.`type`, `FUN_ballons`.`appellation`, `FUN_ballons`.`name`, NULL as `working_time`, NULL as `lifting_height`, NULL as `shell_number`, `FUN_ballons`.`description`, `FUN_ballons`.`price`, `FUN_ballons`.`weight` as `weight`, `FUN_images`.`link` as `photo` FROM `FUN_ballons`, `FUN_images` WHERE `FUN_ballons`.`display` = 'yes' AND `FUN_images`.`type` = 'ballons' AND `FUN_images`.`id_owner` = `FUN_ballons`.`id` AND `FUN_images`.`size` = '120')

   ORDER BY `weight` ASC LIMIT 0,1
)
      UNION
(
   SELECT `FUN_bouquets`.`id`, `FUN_bouquets`.`type`, `FUN_bouquets`.`appellation`, `FUN_bouquets`.`name`, NULL as `working_time`, NULL as `lifting_height`, NULL as `shell_number`, `FUN_bouquets`.`description`, `FUN_bouquets`.`price`, `FUN_bouquets`.`weight` as `weight`, `FUN_images`.`link` as `photo` FROM `FUN_bouquets`, `FUN_images` WHERE `FUN_bouquets`.`display` = 'yes' AND `FUN_images`.`type` = 'bouquets' AND `FUN_images`.`id_owner` = `FUN_bouquets`.`id` AND `FUN_images`.`size` = '120'

   ORDER BY `weight` ASC LIMIT 0,1
)
Я находил похожие проблемы, которые решались введением алиасов для каждой таблицы и началом запроса как SELECT * FROM. Но зачем это делается, так и не понял.

-~{}~ 30.12.07 16:53:

Решил проблему следующим методом
PHP:
SELECT (список полей) FROM
(
  (SELECT) UNION (SELECT) UNION (SELECT) ORDER
) AS `TABLE_1`
SELECT (список полей) FROM
(
 SELECT
) AS `TABLE_2`
Хотя, подозреваю, что во втором случае обобщающий SELECT лишний.

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

FractalizeR

Новичок
Мне кажется, вы неправильно пользуетесь конструкцией ORDER BY в сочетании с UNION. Мануал на этот счет говорит следующее:

=========================================

To use an ORDER BY or LIMIT clause to sort or limit the entire UNION result, parenthesize the individual SELECT statements and place the ORDER BY or LIMIT after the last one. The following example uses both clauses:

(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;

This kind of ORDER BY cannot use column references that include a table name (that is, names in tbl_name.col_name format). Instead, provide a column alias in the first SELECT statement and refer to the alias in the ORDER BY. (Alternatively, refer to the column in the ORDER BY using its column position. However, use of column positions is deprecated.)

Also, if a column to be sorted is aliased, the ORDER BY clause must refer to the alias, not the column name. The first of the following statements will work, but the second will fail with an Unknown column 'a' in 'order clause' error:

(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;

To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

Use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows. If ORDER BY appears with LIMIT, it is used to determine the subset of the selected rows to retrieve for the SELECT, but does not necessarily affect the order of those rows in the final UNION result. If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.

To cause rows in a UNION result to consist of the sets of rows retrieved by each SELECT one after the other, select an additional column in each SELECT to use as a sort column and add an ORDER BY following the last SELECT:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;

To additionally maintain sort order within individual SELECT results, add a secondary column to the ORDER BY clause:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;

=========================================

Если вам не трудно, скиньте мне CREATE TABLE запрос для ваших таблиц. Попробую поиграть.

Ваш второй запрос оказался вложенным и как следствие будет долго выполняться, мне кажется.
 
Сверху