Как мог этот SQL...
CREATE TABLE NewTable AS
SELECT A,B,C FROM Table1
minus
SELECT A, B, C From Table2
... составьте новую таблицу с Нулевыми значениями в столбце A, когда ни у одного Table1 или Table2 не было Нулевых значений для в столбце A?
Но с другой стороны, этот SQL...
SELECT * FROM
(
SELECT A,B,C FROM Table1
minus
SELECT A, B, C From Table2
)
WHERE A IS NULL
не возвратите строки!
Это кажется непоследовательным!
Я думаю, что это - ошибка в Oracle.
Конечно, реальный SQL намного более сложен, но я полагаю, что это точно иллюстрирует природу проблемы.
ОБНОВЛЕНИЕ
Вот ФАКТИЧЕСКИЙ SQL:
Я выполнил этот оператор:
CREATE TABLE MyMinus
AS
select
*
FROM
---begin main query
(
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM dw_mgr.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM dw_mgr.po_distributions_curr_fct b,
dw_mgr.po_lines_curr_fct,
dw_mgr.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = dw_mgr.po_lines_curr_fct.f_cuic
AND b.f_line_id = dw_mgr.po_lines_curr_fct.f_line_id
AND dw_mgr.po_lines_curr_fct.f_cuic =
dw_mgr.po_header_curr_fct.f_cuic
AND dw_mgr.po_lines_curr_fct.f_header_id =
dw_mgr.po_header_curr_fct.f_header_id
AND dw_mgr.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND dw_mgr.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
MINUS
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM arch_fct.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM arch_fct.po_distributions_curr_fct b,
arch_fct.po_lines_curr_fct,
arch_fct.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = arch_fct.po_lines_curr_fct.f_cuic
AND b.f_line_id = arch_fct.po_lines_curr_fct.f_line_id
AND arch_fct.po_lines_curr_fct.f_cuic =
arch_fct.po_header_curr_fct.f_cuic
AND arch_fct.po_lines_curr_fct.f_header_id =
arch_fct.po_header_curr_fct.f_header_id
AND arch_fct.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND arch_fct.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
)
И затем это. Обратите внимание, что строки с Нулевыми значениями F_DISTRIBUTION_ID были вставлены в составленную таблицу.
SELECT COUNT(*) from MyMinus WHERE F_DISTRIBUTION_ID IS NULL
- 17 строк
Все же, когда я выполняю это:
select
*
FROM
---begin main query
(
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM dw_mgr.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM dw_mgr.po_distributions_curr_fct b,
dw_mgr.po_lines_curr_fct,
dw_mgr.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = dw_mgr.po_lines_curr_fct.f_cuic
AND b.f_line_id = dw_mgr.po_lines_curr_fct.f_line_id
AND dw_mgr.po_lines_curr_fct.f_cuic =
dw_mgr.po_header_curr_fct.f_cuic
AND dw_mgr.po_lines_curr_fct.f_header_id =
dw_mgr.po_header_curr_fct.f_header_id
AND dw_mgr.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND dw_mgr.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
MINUS
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM arch_fct.po_distributions_curr_fct a
WHERE EXISTS (
SELECT 1
FROM arch_fct.po_distributions_curr_fct b,
arch_fct.po_lines_curr_fct,
arch_fct.po_header_curr_fct
WHERE a.ROWID = b.ROWID
AND b.f_cuic = arch_fct.po_lines_curr_fct.f_cuic
AND b.f_line_id = arch_fct.po_lines_curr_fct.f_line_id
AND arch_fct.po_lines_curr_fct.f_cuic =
arch_fct.po_header_curr_fct.f_cuic
AND arch_fct.po_lines_curr_fct.f_header_id =
arch_fct.po_header_curr_fct.f_header_id
AND arch_fct.po_header_curr_fct.f_header_creation_date <
ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'),
-48)
AND arch_fct.po_header_curr_fct.f_po_status IN
('CLOSED', 'FINALLY CLOSED'))
)
WHERE
f_distribution_id is null
Я получаю 0 строк.
Почему действительно вставляет записи во временную таблицу, кажется, начинают строки с ПУСТЫХ идентификаторов DIST?
Это минус запрос SQL, который был сгенерирован динамично пользовательской программой архивирования данных, пытается проверить, что данные, которые ДОЛЖНЫ быть заархивированы в схеме DW_MGR, были на самом деле скопированы в ARCH_FCT (архив) схема. Это возвращает различия, которые включали 17 записей, где F_DISTRIBUTION_ID в таблице временного файла MyMinus не соответствуют тем, которые в исходной таблице DW_MG.PO_DISTRIBUTIONS_CURR_FCT, потому что они, являются ПУСТЫМИ. Следовательно, процесс архивирования является дизайном, когда различия найдены. Вопрос состоит в том, почему там различия, т.е. как Нулевые значения входили в таблицу MyMinus, когда они не находятся в таблице SOURCE PO_DISTRIBUTIONS_CURR_FCT?
Править:
Может кто-то с Oracle доступ META, отправьте информацию о thd после ошибок Oracle. Я был направлен к ним, но я заключаю контракт, определил местоположение кого-то в моем co, кто может сказать мне, каков наш идентификатор поддержки #. Я узнаю в конечном счете, но было бы хорошо знать раньше. Если Вы не отправили бы его, рассмотрите следующие ссылки ошибки как потенциально связанную информацию о моем вопросе:
Bug 8209309: MINUS IS SHOWING DIFFERENCES WITH CTAS + INSERT
Bug 7834950: WRONG RESULTS WITH MINUS OPERATOR
Перестань ломать себе голову. Это ошибка Oracle. Я докажу это вам:
Прежде всего, это должен быть первый SQL, который возвращает NULL для ИДЕНТИФИКАЦИИ РАСПРЕДЕЛЕНИЯ, поэтому выделите этот SQL и назовите его «SQL1».
Хорошо, давайте упростим SQL1 для обсуждения и скажем, что он имеет следующий формат:
CREATE TABLE TempTable AS
SELECT
F_DISTRIBUTION_ID,
FIELD2,
FIELD3,...FIELD99
FROM WHATEVER
WHERE WHATEVER
Затем вы обнаруживаете, что, выполняя это, вы обнаруживаете строки с NULL DIST ID:
SELECT COUNT(*) FROM TempTable WHERE F_DISTRIBUTION_ID IS NULL
--Some positive number of rows returned.
Если Oracle не был дерьмом, вы можете изменить количество выбранных полей так, чтобы был выбран только F_DISTRIBUTION_ID, и вы получили бы тот же результат, когда подсчитали количество строк со значением NULL F_DISTRIBUTION_ID, верно? Верно! Но это не так, потому что Oracle - ненадежный динозавр.
Попробуйте следующее:
CREATE TABLE TempTable AS
SELECT
F_DISTRIBUTION_ID
FROM WHATEVER
WHERE WHATEVER
SELECT COUNT(*) FROM TempTable WHERE F_DISTRIBUTION_ID IS NULL
Бьюсь об заклад, долларов на пончики, если вы вернете 0 строк.
Теперь позвоните в Microsoft и скажите, что хотите перейти на SQL Server 2008 R2.
Во-первых, я бы избавился от соединения ROWID с ROWID. Тогда я бы сделал таблицу aiases уникальной (без повторного использования «a» и «b» в запросе над MINUS и запросе под MINUS).
Наконец, я бы посмотрел на эти 17 строк и попытался найти совпадающие записи в "dw_mgr.po_distributions_curr_fct" и посмотреть, используя DUMP (F_DISTRIBUTION_ID), где есть что-то странное в значениях столбцов.
Обычно не должен.
Единственный раз, когда это возможно, это если у вас есть некоторые расширенные функции безопасности (детальный контроль доступа), в соответствии с которыми оптимизатор может видеть, что A не может быть null в table1/ table2, поэтому возвращает нулевые строки, но FGAC включается, чтобы вы не видели фактические значения в столбце, возвращая null.
РЕДАКТИРОВАТЬ. «При маскировки столбцов [Virtual Private Database] отображаются все строки, даже те, которые ссылаются на чувствительные столбцы. Однако конфиденциальные столбцы отображаются в виде значений NULL. "
http://download.oracle.com/docs/cd/E11882_01/network.112/e10574/vpd.htm#i1014682
Единственный способ, которым я могу думать, что F_DISTRIBUTION_ID может быть NULL при вставке в MyMinus, это если он возвращает NULL каким-то образом, каким-то образом в первом запросе.
Чтобы воспроизвести это (как на 9i, так и на 10g):
SQL> INSERT INTO table1 VALUES (NULL, 2, 3);
1 row created.
SQL> INSERT INTO table2 VALUES (1, 2, 3);
1 row created.
SQL> SELECT *
2 FROM (
3 SELECT a, b, c FROM table1
4 MINUS
5 SELECT a, b, c FROM table2);
A B C
---------- ---------- ----------
2 3
Однако, что касается того, что запрос не возвращает строк при выполнении сам по себе... это что-то другое. Ошибка меня не удивит... но вы пробовали убрать эти EXISTS? Конечно, есть много разных подходов, но, возможно, все эти подзапросы вызывают что-то забавное в памяти.
For example:
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM dw_mgr.po_distributions_curr_fct a
dw_mgr.po_lines_curr_fct,
dw_mgr.po_header_curr_fct
WHERE a.f_cuic = dw_mgr.po_lines_curr_fct.f_cuic
AND a.f_line_id = dw_mgr.po_lines_curr_fct.f_line_id
AND dw_mgr.po_lines_curr_fct.f_cuic = dw_mgr.po_header_curr_fct.f_cuic
AND dw_mgr.po_lines_curr_fct.f_header_id = dw_mgr.po_header_curr_fct.f_header_id
AND dw_mgr.po_header_curr_fct.f_header_creation_date < ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'), -48)
AND dw_mgr.po_header_curr_fct.f_po_status IN ('CLOSED', 'FINALLY CLOSED')
MINUS
SELECT expenditure_item_date, expenditure_org, expenditure_type,
f_amount_billed, f_amount_billed_fc, f_amount_billed_us,
f_bl_creation_date, f_catalog_source, f_catalog_type, f_company,
f_company_code, f_cost_center_num, f_cuic, f_currency_code,
f_destination_type_code, f_distribution_id, f_distribution_num,
f_exchange_rate, f_extract_date, f_gl_account,
f_isms_jamis_project_num, f_line_id, f_local_use, f_location_num,
f_need_by_date, f_org_id, f_po_line_num, f_po_num, f_po_release_num,
f_project, f_project_num, f_promised_date, f_quantity_billed,
f_quantity_cancelled, f_quantity_delivered, f_quantity_ordered,
f_rel_approved_flag, f_rel_cancelled_flag, f_rel_cancel_date,
f_rel_closed_code, f_rel_hold_flag, f_rel_revision_num, f_task_num
FROM arch_fct.po_distributions_curr_fct a,
arch_fct.po_lines_curr_fct,
arch_fct.po_header_curr_fct
WHERE a.f_cuic = arch_fct.po_lines_curr_fct.f_cuic
AND a.f_line_id = arch_fct.po_lines_curr_fct.f_line_id
AND arch_fct.po_lines_curr_fct.f_cuic = arch_fct.po_header_curr_fct.f_cuic
AND arch_fct.po_lines_curr_fct.f_header_id = arch_fct.po_header_curr_fct.f_header_id
AND arch_fct.po_header_curr_fct.f_header_creation_date < ADD_MONTHS (TRUNC (SYSDATE, 'YEAR'), -48)
AND arch_fct.po_header_curr_fct.f_po_status IN ('CLOSED', 'FINALLY CLOSED')