2011-03-09 2 views
6

성능상의 이유로 논리적으로 하나의 테이블을 조각으로 나눈 테이블 세트가 있습니다. 모든 테이블을 효율적으로 조인하는 쿼리를 작성해야하므로 결과의 단일 where 절을 사용합니다. 내가 성공적으로의 WHERE 절을 사용하여 결과에 UNION을 사용하고 각 서브 테이블에 명시 적으로 다음과 같은UNION 쿼리를 하위 쿼리로 처리하는 방법

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 

NEW 정보 :

문제가 무엇보다도 노동 조합의 필드의 수 기능과 더 많은 관계를 가지고있다처럼 보인다. 필드를 크게 제한하면 작동하는 구문 변형의 대부분을 얻을 수 있습니다. 불행하게도 필드를 너무 많이 제한하면 결과 쿼리가 유용 할 수 있지만 원하는 결과를 얻지 못합니다. 나는 2 개의 키 이외에 테이블 중 하나에서 추가로 3 개의 필드를 얻을 수 있었다. 그 이상이면 쿼리가 실패합니다.

+3

는 구문 오류가 발생합니까? UNION이 아닌 UNION ALL을 사용하면 제대로 작동합니다. 그런 다음 노조를 뷰에 넣고 파티셔닝을 다시 시작했습니다. – araqnid

+0

이 "분할 테이블"전략은 식별 된 비관적 기술입니다. – dkretz

+0

나는 실제로 비관론이 의미하는 바를 찾아야 만했다 :-) 그런데, 테이블 아이디어를 나누는 것은 약 10 살 정도의 응용 프로그램의 일부이기 때문에 그것에 대해 많이 할 수는 없다. –

답변

24

하위 쿼리 결과에 이름을 지정해야한다고 생각합니다. 나는 어둠 속에서 총을 맞고 있으므로 db2를 모르지만, 다른 여러 플랫폼에서 작동한다는 것을 알고 있습니다.

SELECT * 
FROM (
    SELECT * FROM FRED_1 
    UNION 
    SELECT * FROM FRED_2 
    UNION 
    SELECT * FROM FRED_3) AS T1 
WHERE CHARLIE = 42 
+0

하나의 테이블 그룹 (노동 조합)의 단순한 경우에 작동하지만 다른 유사한 그룹 T2에 가입하려는 경우 작동하지 않습니다 –

+0

원래 쿼리에서 오류가 발생하거나 원하는 결과를 반환하지 않습니까? – Infotekka

+0

SQL0136, SQLCODE -136, "ORDER BY 또는 GROUP BY 열이 너무 깁니다"를 의미하는 SQLSTATE 54005 오류가 발생합니다. 문제는 내가 쿼리에 ORDER BY 또는 GROUP BY가 없어도이 문제가 발생합니다. 그러나 나는 30 개의 테이블을 가지고있다. (각 그룹은 10 개의 3 그룹으로 구성되며 각 그룹은 다음 키와 관련이있다 (T1.KEY = T2.KEY 및 T2.KEY = T3.KEY 및 T2.KEY2 = T3.KEY2)) –

1

나는 DB2 구문에 익숙하지 않아요하지만 당신은 왜 INNER JOIN 또는 LEFT JOIN int로서이 일을하지 않습니다? 값이 FRED_2 또는 FRED_3에 존재하지 않는 경우

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 

다음 LEFT/OUTER JOIN를 사용합니다. FRED_1이 마스터 테이블이고 레코드가 있으면이 테이블에 있다고 가정합니다.

+0

실제로 FRED는 여러 부분으로 나뉘어 진 테이블입니다. 1-10이 서브 테이블 중 하나에서만 키가 발생합니다. –

2

논리 구현이 단일 테이블이지만 물리적 구현이 여러 테이블 인 경우 논리 모델을 정의하는보기를 작성하는 방법은 어떻습니까?

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

그런 다음 내가 DB2 구문에 익숙하지 않은 해요, 다시

SELECT * FROM VW_FRED WHERE CHARLIE = 42 

의 간단한 문제입니다 그러나 이것은 당신에게 일반적인 아이디어를 제공합니다.

+0

뷰를 만들 수있게되면 이것은 좋을 것입니다 ... 메인 프레임에 설치된 DB2는 DB2에 "필요"합니다 DEV를 위해 모든 수정 사항을 "관리"하는 그룹. –

0
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 
+0

조합을 포함하자마자 SQLCODE -136 SQLSTATE 54005 (정렬 키가 너무 길거나 열이 너무 많음)가 표시됩니다. 이 구문은 유니온을 지정하지 않으면 작동합니다. –

0

어쩌면 :

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

이것과 변형을 시도 할 때 동일한 문제 (SQLSTATE 54005)가 발생합니다. –

+0

모든 테이블의 모든 필드가 필요합니까? 어쩌면 특정 필드를 지정하여 정렬 키에 대해 너무 많은 열을 갖지 않게 할 수 있습니까? – Leslie

+0

나는 그것을 시도하고 오직 두 개의 키 이외의 세 개의 추가 필드를 얻을 수있다. 대부분의 경우 저에게 유용하지 않습니다. –

관련 문제