2016-11-08 6 views
-2

можно достичь нижеследующего вывода из таблицы 1 и таблицы 2 Я пробовал все соединения, такие как внешнее соединение, левое соединение, правое соединение, но требуемый выход не достигается output .пожалуйста, помогите мне , спасибоПрисоединиться к Oracle SQL

+0

вы можете использовать 'Union' –

+4

http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload- image-of-code-on-so-when-ask-a-question/285557 # 285557 –

+2

Вы пробовали что-нибудь? Отправьте свой код. Кроме того, отредактируйте свой вопрос, чтобы отобразить данные как форматированный текст, а не изображения. – Aleksej

ответ

0

Это может быть легко достигнуто с помощью partition outer join:

WITH table1 AS (SELECT 2014 yr, 'Main' division, 2000 amt FROM dual UNION ALL 
       SELECT 2015 yr, 'Main' division, 6000 amt FROM dual UNION ALL 
       SELECT 2016 yr, 'Main' division, 7000 amt FROM dual), 
    table2 AS (SELECT 2014 yr, 'Center' division, 100 amt FROM dual UNION ALL 
       SELECT 2015 yr, 'Center' division, 200 amt FROM dual UNION ALL 
       SELECT 2016 yr, 'Center' division, 350 amt FROM dual), 
-- end of mimicking your tables; you wouldn't need the above 
-- as you already have the tables. 
-- You will need the following subquery to define the years you're querying 
-- against, though. You can define this either in the WITH clause 
-- or as an inline view in the main SQL below 
     years AS (SELECT 2014 yr FROM dual UNION ALL 
       SELECT 2015 yr FROM dual UNION ALL 
       SELECT 2016 yr FROM dual UNION ALL 
       SELECT 2017 yr FROM dual) 
SELECT yrs.yr, 
     t.division, 
     NVL(t.amt, 0) amt 
FROM years yrs 
     LEFT OUTER JOIN (SELECT yr, division, amt FROM table1 
         UNION ALL 
         SELECT yr, division, amt FROM table2) t PARTITION BY (t.division) 
      ON yrs.yr = t.yr 
ORDER BY t.division, yrs.yr; 

     YR DIVISION  AMT 
---------- -------- ---------- 
     2014 Center   100 
     2015 Center   200 
     2016 Center   350 
     2017 Center   0 
     2014 Main   2000 
     2015 Main   6000 
     2016 Main   7000 
     2017 Main    0 
0

Мне не нравится запрос, но я думаю, что он даст ваш результат. Если бы вы предоставили тестовые данные в качестве вставок, я бы протестировал их.

with years as (select year from select year from table1 union select year from table2), 
    divisions as (select division from select division from table1 union select division from table2) 
select y.year, d.division, nvl(t1.amd, 0) 
    from years y cross join divisions d 
    left outer join table1 t1 on (y.year = t1.year and d.division = t1.division) 
union all 
select y.year, d.division, nvl(t2.amd, 0) 
    from years y cross join divisions d 
    left outer join table2 t2 on (y.year = t2.year and d.division = t2.division); 
+2

'y inner join d on (1 = 1)' называется CROSS JOIN и имеет свой собственный синтаксис, который лучше использовать для ясности: 'y перекрестное соединение d'. Кроме того, левое внешнее соединение является дистрибутивным над объединением всех; вы можете сделать 'd cross join y cross join <результат union all>' – mathguy

+0

@mathguy Спасибо, да, ther должно быть «перекрестными» беспорядочными привычками. Я знаю, что могу присоединиться к союзу. Это я сделал просто для ясности. Но, возможно, это более понятно только для меня;) – Kacper

+0

... и, конечно, у меня есть опечатка в комментарии (которую я не могу редактировать) - в конце это должно быть 'y cross join d LEFT OUTER join < ... >' {:-) – mathguy

0

Вы можете использовать UNION и LEFT OUTER JOIN вроде этого:

SELECT * FROM(
SELECT 
    DISTINCT 
    YEARS.YEAR, 
    NVL(T1.DIVISION, (SELECT MAX(DIVISION) FROM TABLE1 WHERE DIVISION IS NOT NULL)) DIVISION, 
    NVL(T1.AMT, 0) 
FROM 
(
    SELECT YEAR, DIVISION FROM TABLE1 
    UNION 
    SELECT YEAR, DIVISION FROM TABLE2 
) YEARS 
LEFT JOIN TABLE1 T1 
ON YEARS.YEAR = T1.YEAR 
) TAB1 
UNION ALL 
(
    SELECT 
    DISTINCT 
    YEARS.YEAR, 
    NVL(T2.DIVISION, (SELECT MAX(DIVISION) FROM TABLE2 WHERE DIVISION IS NOT NULL)) DIVISION, 
    NVL(T2.AMT, 0) 
    FROM 
    (
    SELECT YEAR, DIVISION FROM TABLE1 
    UNION 
    SELECT YEAR, DIVISION FROM TABLE2 
) YEARS 
    LEFT JOIN TABLE2 T2 
    ON YEARS.YEAR = T2.YEAR 
) 
ORDER BY 2 DESC, 1; 
1

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

Более поздний метод - «Разделенное внешнее соединение».

Существует хорошая запись на них в «SQL для отчетов и анализ» Руководства: https://docs.oracle.com/cd/E11882_01/server.112/e25555/tdpdw_sql.htm#TDPDW0072

Have обзора этого, и если вы не можете выработать правильный синтаксис, то, возможно, задать новый вопрос сфокусирован на использовании секционированных внешних объединений.

Смежные вопросы