Как я могу рассматривать запрос UNION как подзапрос

У меня есть набор таблиц, которые логически представляют собой одну таблицу, разделенную на части по соображениям производительности. Мне нужно написать запрос, который эффективно объединяет все таблицы вместе, поэтому я использую одно предложение where результата. Я успешно использовал UNION в результате использования предложения WHERE в каждой подтаблице явно, как показано ниже.

SELECT * FROM FRED_1 WHERE CHARLIE = 42
UNION 
SELECT * FROM FRED_2 WHERE CHARLIE = 42
UNION 
SELECT * FROM FRED_3 WHERE CHARLIE = 42

но так как есть десять отдельных подтаблиц, обновлять предложение WHERE каждый раз неудобно. Я хочу что-то вроде этого

SELECT * 
FROM (
    SELECT * FROM FRED_1 
    UNION 
    SELECT * FROM FRED_2 
    UNION 
    SELECT * FROM FRED_3) 
WHERE CHARLIE = 42

Если это имеет значение, запрос необходимо выполнить для базы данных DB2.

Вот более полная (очищенная) версия того, что мне нужно сделать.

select * 
from ( select * from FRD_1 union select * from FRD_2 union select * from FRD_3 ) as FRD, 
     ( select * from REQ_1 union select * from REQ_2 union select * from REQ_3 ) as REQ, 
     ( select * from RES_1 union select * from RES_2 union select * from RES_3 ) as RES 
where FRD.KEY1 = 123456
  and FRD.KEY1 = REQ.KEY1
  and FRD.KEY1 = RES.KEY1
  and REQ.KEY2 = RES.KEY2

НОВАЯ ИНФОРМАЦИЯ:

Похоже, проблема больше связана с количеством полей в объединении, чем с чем-либо еще. Если я сильно ограничу поля, я смогу заставить работать большинство вариантов синтаксиса ниже. К сожалению, такое сильное ограничение полей означает, что результирующий запрос, хотя и потенциально полезный, не дает мне желаемого результата. Мне удалось получить дополнительные 3 поля из одной из таблиц в дополнение к 2 ключам. Еще больше, и запрос не выполняется.


person Michael Rutherfurd    schedule 09.03.2011    source источник
comment
Этот синтаксис вызывает ошибку? Если вы используете UNION ALL, а не UNION, это может работать нормально. Затем вы помещаете объединения в представление и заново изобретаете разделение...   -  person araqnid    schedule 09.03.2011
comment
Вы понимаете, что эта стратегия «разделения стола» — известная техника пессимизации?   -  person dkretz    schedule 09.03.2011
comment
На самом деле мне пришлось посмотреть, что означает пессимизация :-) Сказав это, идея разделения таблицы является частью приложения, которому около 10 лет, поэтому я мало что могу с этим поделать.   -  person Michael Rutherfurd    schedule 09.03.2011


Ответы (5)


Я считаю, что вы должны дать имя вашему результату подзапроса. Я не знаком с db2, поэтому я делаю попытку в темноте, но я знаю, что это работает на нескольких других платформах.

SELECT * 
FROM (
    SELECT * FROM FRED_1 
    UNION 
    SELECT * FROM FRED_2 
    UNION 
    SELECT * FROM FRED_3) AS T1
WHERE CHARLIE = 42
person Infotekka    schedule 09.03.2011
comment
Это работает в простом случае одной группы таблиц (объединения), но не работает, если я хочу присоединиться к другой аналогичной группе T2 - person Michael Rutherfurd; 09.03.2011
comment
Выдает ли исходный запрос ошибку или он просто не возвращает желаемых результатов? - person Infotekka; 09.03.2011
comment
Я получаю сообщение об ошибке SQL0136, SQLCODE -136, SQLSTATE 54005, что означает, что столбцы ORDER BY или GROUP BY слишком длинные. Проблема в том, что я получаю это, хотя в моем запросе нет ORDER BY или GROUP BY. Однако у меня есть 30 таблиц (3 группы по 10, каждая группа связана со следующей по ключу (T1.KEY = T2.KEY и T2.KEY = T3.KEY и T2.KEY2 = T3.KEY2)) - person Michael Rutherfurd; 10.03.2011
comment
Можете ли вы опубликовать свой SQL, к которому вы пытаетесь присоединиться? Я делаю это (присоединяюсь к результату запроса) все время на DB2, и у меня нет проблем. - person Leslie; 10.03.2011
comment
@Leslie Добавлено больше деталей внизу вопроса - person Michael Rutherfurd; 11.03.2011
comment
Это работало для меня на IBM DB2 SQL, но следует отметить, как упоминалось в первом комментарии выше: это было для простого подзапроса из, который содержал объединение нескольких таблиц без соединений ни внутри, ни снаружи подзапроса. - person spinjector; 30.11.2017
comment
Кстати, это было для DB2 v6. - person spinjector; 30.11.2017

Если логическая реализация представляет собой одну таблицу, а физическая реализация представляет собой несколько таблиц, то как насчет создания представления, определяющего логическую модель.

CREATE VIEW VW_FRED AS 
SELECT * FROM FRED_1 
UNION    
SELECT * FROM FRED_2 
UNION    
SELECT * FROM FRED_3

тогда это просто вопрос

SELECT * FROM VW_FRED WHERE CHARLIE = 42

Опять же, я не знаком с синтаксисом db2, но это дает вам общее представление.

person Dave Barker    schedule 09.03.2011
comment
Было бы здорово, если бы мне разрешили создавать представления... локально DB2, установленная на мейнфрейме, нуждается в группе DB2 для управления всеми модификациями даже для DEV. - person Michael Rutherfurd; 09.03.2011

Я не знаком с синтаксисом DB2, но почему вы не делаете это как INNER JOIN или LEFT JOIN?

SELECT * 
  FROM FRED_1
 INNER JOIN FRED_2
    ON FRED_1.Charlie = FRED_2.Charlie
 INNER JOIN FRED_3
    ON FRED_1.Charlie = FRED_3.Charlie
 WHERE FRED_1.Charlie = 42

Если значения не существуют в FRED_2 или FRED_3, используйте LEFT/OUTER JOIN. Я предполагаю, что FRED_1 является главной таблицей, и если запись существует, то она будет в этой таблице.

person Dave Barker    schedule 09.03.2011
comment
На самом деле FRED - это таблица, разделенная на несколько частей 1-10, ключ будет встречаться в одной и только одной из этих подтаблиц. - person Michael Rutherfurd; 09.03.2011

может быть:

SELECT * FROM 
(select * from FRD_1 
union 
select * from FRD_2 
union 
select * from FRD_3) FRD
INNER JOIN (select * from REQ_1 union select * from REQ_2 union select * from REQ_3) REQ
  on FRD.KEY1 = REQ.KEY1
INNER JOIN (select * from RES_1 union select * from RES_2 union select * from RES_3) RES
  on FRD.KEY1 = RES.KEY1
WHERE FRD.KEY1 = 123456 and REQ.KEY2 = RES.KEY2
person Leslie    schedule 11.03.2011
comment
Я получаю ту же проблему (SQLSTATE 54005) при попытке этого и вариантов - person Michael Rutherfurd; 12.03.2011
comment
ну вам нужно каждое поле из каждой таблицы? может быть, указав определенные поля, у вас не будет слишком много столбцов для ключа сортировки? - person Leslie; 14.03.2011
comment
Я попробовал это, и я могу получить только три дополнительных поля (кроме двух ключей). Мне это в большинстве случаев бесполезно - person Michael Rutherfurd; 15.03.2011

person    schedule
comment
Я получаю SQLCODE -136 SQLSTATE 54005 (ключ сортировки слишком длинный или содержит слишком много столбцов), как только я включаю какие-либо объединения. Этот синтаксис работает, если я не указываю союзы. - person Michael Rutherfurd; 12.03.2011