아래 쿼리는 postgres에서는 잘되는데
오라클에서는 병렬질의... 열은 하위 질의에 포괄 조인될 수 없습니다 라고 에러 발생하는 거 같습니다
실무 쿼리 비슷하게 만든 쿼리라 저 쿼리가 오라클에서 에러가 나는지 확인은 안해봤구요
아래 쿼리와 비슷한 실무 쿼리는 에러가 납니다
아래 쿼리는
select 구문1
union all
select 구문2
이런 형식인데 select구문에서 left outer join 에 서브 쿼리로 되있어서 에러가 발생 하는거같습니다
각각의 select구문1, select구문2를 단독으로 실행하면 오라클에서는 잘 실행되는데
union all로 묶어서 실행하면 에러가 납니다
한 쿼리로 잘되게 실행되는 방법이 있을까요?
--국내
select
t1.lss_id as lss_id
,max(t1.store) as store
,sum(
case t1.loss_profit
when 'loss' then t1.amount
else 0
end
) as loss_amount
from
domestic_store_loss t1
where t1.store = case 'ALL'
when 'ALL' then t1.store
when 'AAAA' then 'AAAA'
when 'BBBB' then 'BBBB'
when 'BANK' then 'BANK'
end
group by t1.lss_id
union all
--국외
select
tm.lss_id
,tm.store
,tm.loss_amount
from
(
select
t1.lss_id as lss_id
,max(t2.store) as store
,sum(
case t2.store
when 'AAAA' then
case
when t2.account = '1' or t2.account = '2' or t2.account = '3'
then
case t2.loss_profit
when 'loss' then t2.amount * t_bs.xrt
else 0
end
when t2.account = '4' or t2.account = '5' or t2.account = '6'
then
case t2.loss_profit
when 'loss' then t2.amount * t_is.xrt
else 0
end
else 0
end
when 'BBBB' then
case
when t2.account = '7' or t2.account = '8'
then
case t2.loss_profit
when 'loss' then t2.amount * t_bs.xrt
else 0
end
when t2.account = '9' or t2.account = '0'
then
case t2.loss_profit
when 'loss' then t2.amount * t_is.xrt
else 0
end
else 0
end
else 0
end
) as loss_amount
from
oversea_store_loss t1
left outer join oversea_store_loss_detail t2
on t1.lss_id = t2.lss_id
and t1.store = t2.store
left outer join exchange_rate t_is
on t2.reg_date = t_is.reg_date
left outer join (
select
substring(reg_date, 1, 4) reg_year
,currency
,round(avg(xrt), 2) as xrt
from
exchange_rate
group by substring(reg_date, 1, 4), currency
) t_bs
on substring(t2.reg_date, 1, 4) = reg_year
where
1 = 1
group by t1.lss_id
order by 1
) tm
where
tm.loss_amount > 9000000
and tm.store = case 'ALL'
when 'ALL' then tm.store
when 'AAAA' then 'AAAA'
when 'BBBB' then 'BBBB'
when 'BANK' then 'BANK'
end
;
---------------------------
-- Table: public.domestic_store_loss
-- DROP TABLE IF EXISTS public.domestic_store_loss;
CREATE TABLE IF NOT EXISTS public.domestic_store_loss
(
lss_id text COLLATE pg_catalog."default" NOT NULL,
store text COLLATE pg_catalog."default" NOT NULL,
reg_date text COLLATE pg_catalog."default" NOT NULL,
loss_profit text COLLATE pg_catalog."default" NOT NULL,
amount bigint,
CONSTRAINT domestic_store_loss_pkey PRIMARY KEY (lss_id, store, reg_date, loss_profit)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.domestic_store_loss
OWNER to postgres;
-- Table: public.exchange_rate
-- DROP TABLE IF EXISTS public.exchange_rate;
CREATE TABLE IF NOT EXISTS public.exchange_rate
(
reg_date text COLLATE pg_catalog."default" NOT NULL,
currency text COLLATE pg_catalog."default" NOT NULL,
xrt bigint,
CONSTRAINT exchange_rate_pkey PRIMARY KEY (reg_date, currency)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.exchange_rate
OWNER to postgres;
COMMENT ON TABLE public.exchange_rate
IS '환율정보';
-- Table: public.oversea_store_loss
-- DROP TABLE IF EXISTS public.oversea_store_loss;
CREATE TABLE IF NOT EXISTS public.oversea_store_loss
(
lss_id text COLLATE pg_catalog."default" NOT NULL,
store text COLLATE pg_catalog."default",
reg_date text COLLATE pg_catalog."default",
CONSTRAINT oversea_store_loss_pkey PRIMARY KEY (lss_id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.oversea_store_loss
OWNER to postgres;
-- Table: public.oversea_store_loss_detail
-- DROP TABLE IF EXISTS public.oversea_store_loss_detail;
CREATE TABLE IF NOT EXISTS public.oversea_store_loss_detail
(
lss_id text COLLATE pg_catalog."default" NOT NULL,
store text COLLATE pg_catalog."default" NOT NULL,
account text COLLATE pg_catalog."default" NOT NULL,
reg_date text COLLATE pg_catalog."default" NOT NULL,
loss_profit text COLLATE pg_catalog."default" NOT NULL,
amount bigint,
CONSTRAINT oversea_store_loss_detail_pkey PRIMARY KEY (lss_id, store, account, reg_date, loss_profit)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.oversea_store_loss_detail
OWNER to postgres;
---------------------------
1. 잘 되는 포스그레 쿼리를 올려 주셨네요?
- 구문에는 문제가 없어 보이는데요?
- 안되는 오라클 쿼리를 보여주세요.
2. 그리고 exchange_rate 테이블을 두번 사용하는데?
- 왜 이래야 하는지 모르겠네요?
- 잘 못 사용한 느낌이 듭니다.
잘 못 사용한 느낌이 든다면 어떻게 해야 잘 사용하는건지 예시 좀 부탁드려요 실제 쿼리를 여기에 공개하기는 좀 그래서요
exchange_rate 테이블 자체가 t_is
연도별 평균이 t_bs 로 해서 두번 사용하는데
결국 연평균 값을 다시 합산하고 있는데
이는 그녕 값을 합산한 것과 같은 것 아닌가요?
case 식이 좀 복잡하여 다를 수도 있을 것 같기도 하고 아닐 것 같기도 하고.
실데이터를 확인하지 못한 상태에서의 추측일 뿐입니다.
그리고 쿼리는 이미 올려주신 것 아닌가요?
올려주신 쿼리가 실제 쿼리가 아닌 모양이네요?
가공이 들어간 모양인데? 가공을 하면서 실제 쿼리와 다른 쿼리가 되었을 수도 있습니다.
올려주신 쿼리는 뭔가 이상하다는 느낌은 있지만 오류가 날 것 같지는 않습니다.
일반적인 오류가 아닌 이상한 오류는 피해 가야 하는데.
테스트가 가능한 상황이 아니라
답변 드리기가 모호한 부분이 있네요.
회사에서 인터넷 피씨가 없어서 모바일로만 글을써야되서요 아쉽습니다 실제 쿼리는 더 복잡하더라고요 제가 작성하고도 집에서 기억을 더듬어 샘플을 만든거라서요 실제쿼리에서는 이게 국외점포에서 환율쪽을 연평균환율과 일자별 환율 정보를 다가지고 계산을 해야되서 환율테이블을 두번 아우터 조인하더라고요 그래서 a조건일땐 연평균환율사용하고 b조건일땐 일자별환율 사용하는식입니다 이게 유니온으로 묶기전에는 각각의 셀렉트는 오류없는데 유니온으로 묶으면 ORA-12801, ORA-01799 에러가 납니다
각각은 오류가 없는데 UNION 하면 오류난다면?
뭔가 쿼리 변환하면서 문제가 발생되는게 아닌가 셍각되는데요.
각각의 쿼리 SELECT 절에 ROWNUM 을 하나씩 추가해 보세요. (쿼리 변환 방지용)
아 찾았습니다 이게 국외쪽이아니라 국내점포쪽에 아웃터 조인쪽에 on 조건절에 서브쿼리있어서 그런거같습니다 감사합니다
마농님 같이 고민해줘서 큰힘 되었습니다
네. 맞습니다.
아우터 조인에 서브쿼리 조건 사용하면 나는 오류입니다.
하지만 질문의 쿼리엔 그게 없어서 오류 날 것 같지 않다고 한거였죠.
본래 쿼리를 올릴 수 없어 간략하게 가공하여 올리는 경우라 하더라도
핵심이 빠진 전혀 다른 쿼리로 질문하시면 도움 받기 힘듭니다.
가공은 하되 왜곡은 하면 안됩니다.
네 감사합니다 마농님 교육 찾아서 봐야겠습니다