Oracle SQL UNION ALL, где T1.ID ‹› T2.ID

У меня есть две таблицы Test_Table и Test_Table2. Мне нужны UNION ALL или UNION из двух, но мне нужны только строки из TEST_TABLE2, для которых у меня нет идентификатора в TEST_TABLE. Идентификаторы могут быть уникальными для любой таблицы или существовать в обеих таблицах, поскольку они заполняются из двух разных систем.

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

SELECT ID, DATE_VALUE, TEXT_VALUE, TABLESOURCE FROM TEST_TABLE
UNION
SELECT ID, OTHER_DATE_VALUE AS DATE_VALUE, OTHER_TEXT_VALUE AS TEXT_VALUE, TABLESOURCE FROM TEST_TABLE2;

Вот столы.

http://sqlfiddle.com/#!2/2db484/2

Я использую "Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 — 64-битная производственная версия"

Я не смог заставить SQL сделать это. Как я могу получить эти строки.


person Scheballs    schedule 18.08.2014    source источник


Ответы (2)


Вы можете оставить соединение Test_Table с TestTable2, чтобы найти строки, которые не совпадают:

SELECT 
  ID, DATE_VALUE, TEXT_VALUE, TABLESOURCE 
FROM TEST_TABLE
UNION -- or UNION ALL, which might be faster
SELECT 
  t2.ID, t2.OTHER_DATE_VALUE AS DATE_VALUE, t2.OTHER_TEXT_VALUE AS TEXT_VALUE, t2.TABLESOURCE 
FROM 
  TEST_TABLE2 t2
  LEFT JOIN TEST_TABLE t on t.ID = t2.ID
WHERE
  t.ID IS NULL

http://sqlfiddle.com/#!2/2db484/6

В качестве альтернативы вы можете использовать WHERE NOT EXISTS ... для возврата только строк для t2, у которых нет соответствующей строки в t:

SELECT 
  ID, DATE_VALUE, TEXT_VALUE, TABLESOURCE 
FROM TEST_TABLE
UNION -- or UNION ALL, which might be faster
SELECT 
  ID, 
  OTHER_DATE_VALUE, -- Note, you don't need the alias in the second query of the union.
  OTHER_TEXT_VALUE AS TEXT_VALUE, -- Although you can leave it as 'self-documentation'.
  TABLESOURCE 
FROM 
  TEST_TABLE2 t2
WHERE
  NOT EXISTS 
    (SELECT 'x' FROM TEST_TABLE t WHERE t.ID = t2.ID)

Кроме того, взгляните на MINUS и INTERSECT, которые можно использовать точно так же, как UNION, но для создания набора данных, не совпадающего с записью в другом, или набора данных по тем записям, которые соответствуют другому набору данных. См.: http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries004.htm

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

person GolezTrol    schedule 18.08.2014
comment
Спасибо, я попробовал «Где не существует», и это дало мне именно то, что мне нужно. - person Scheballs; 18.08.2014

Я бы написал это как:

SELECT ID, DATE_VALUE, TEXT_VALUE, TABLESOURCE
FROM TEST_TABLE
UNION ALL
SELECT ID, OTHER_DATE_VALUE AS DATE_VALUE, OTHER_TEXT_VALUE AS TEXT_VALUE, TABLESOURCE
FROM TEST_TABLE2 T2
WHERE NOT EXISTS (SELECT 1 FROM TEST_TABLE T WHERE T.ID = T2.ID);

Поскольку вы выбираете разные id, вам не нужны union. union all более эффективен, поскольку не добавляет шаг удаления дубликатов.

person Gordon Linoff    schedule 18.08.2014
comment
Спасибо, я изменил свое заявление на Union All, так как Union не обрабатывал дубликаты, о которых я заботился. Союз Все работает намного быстрее. - person Scheballs; 18.08.2014