Как я могу рассматривать запрос UNION как подзапрос - PullRequest
9 голосов
/ 09 марта 2011

У меня есть набор таблиц, которые логически разделены на части по соображениям производительности. Мне нужно написать запрос, который эффективно объединяет все таблицы вместе, поэтому я использую одно предложение 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 ключам. Более того, запрос не выполняется.

Ответы [ 5 ]

30 голосов
/ 09 марта 2011

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

SELECT * 
FROM (
    SELECT * FROM FRED_1 
    UNION 
    SELECT * FROM FRED_2 
    UNION 
    SELECT * FROM FRED_3) AS T1
WHERE CHARLIE = 42
2 голосов
/ 09 марта 2011

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

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, но это дает вам общее представление.

1 голос
/ 09 марта 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 является основной таблицей, и если запись существует, она будет в этой таблице.

0 голосов
/ 11 марта 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
0 голосов
/ 10 марта 2011
with 
FRD as ( select * from FRD_1 union select * from FRD_2 union select * from FRD_3 ), 
REQ as ( select * from REQ_1 union select * from REQ_2 union select * from REQ_3 ), 
RES as ( select * from RES_1 union select * from RES_2 union select * from RES_3 )
SELECT * from FRD, REQ, RES 
WHERE FRD.KEY1 = 123456
and FRD.KEY1 = REQ.KEY1
and FRD.KEY1 = RES.KEY1
and REQ.KEY2 = RES.KEY2
...