Обновление Не работает должным образом в Netezza. Это на самом деле общая тема

Я не понимаю, почему запрос на обновление не работает должным образом или мне не хватает чего-то очень тривиального здесь? Вот последовательность простых шагов, которые я запускаю.

Шаг 1. Создание таблицы

CREATE table SNAPDATE_YOS as SELECT SNAPSHOTDATE, PREFERENCE_ID, CVALIDEMAIL, (CVALIDEMAIL * 1.0125) AS new_CVALIDEMAIL
FROM RPT_EMAIL_CATEGORY_PREFERENCE 
WHERE SNAPSHOTDATE = '2014-07-07 00:00:00'
AND PREFERENCE_ID = 'Yosemite';

1 строка затронута

Select * from SNAPDATE_YOS;

SNAPSHOTDATE || PREFERENCE_ID || CVALIDEMAIL || NEW_CVALIDEMAIL

2014-07-07 00: 00: 00 || Йосемити || 97676 || 98896.9500

Шаг 2: Обновление таблицы RPT_EMAIL_CATEGORY_PREFERENCE для условия соединения с созданной таблицей на шаге 1.

UPDATE RPT_EMAIL_CATEGORY_PREFERENCE
SET CVALIDEMAIL = ROUND(S.new_CVALIDEMAIL,0)
FROM SNAPDATE_YOS S
JOIN RPT_EMAIL_CATEGORY_PREFERENCE P ON P.PREFERENCE_ID = S.PREFERENCE_ID 
WHERE P.SNAPSHOTDATE = '2014-11-21 00:00:00'
AND P.PREFERENCE_ID = 'Yosemite';

Обновлено 34 строки.

По-моему, только одна строка должна быть обновлена, поскольку условие соединения дает мне только одну строку.

Вот поддерживающие утверждения для него.

Оператор поддержки 1: выбор строк в условии.

Select ROUND(S.new_CVALIDEMAIL,0) as CVALIDEMAIL
FROM SNAPDATE_YOS S 
JOIN RPT_EMAIL_CATEGORY_PREFERENCE P ON P.PREFERENCE_ID = S.PREFERENCE_ID 
WHERE P.SNAPSHOTDATE = '2014-11-21 00:00:00'
AND P.PREFERENCE_ID = 'Yosemite';

Вывод:

CVALIDEMAIL

98897

Поддерживающее утверждение 2: выбор всех столбцов

Select *
FROM SNAPDATE_YOS S 
JOIN RPT_EMAIL_CATEGORY_PREFERENCE P ON P.PREFERENCE_ID = S.PREFERENCE_ID 
WHERE P.SNAPSHOTDATE = '2014-11-21 00:00:00'
AND P.PREFERENCE_ID = 'Yosemite';

Выбрана 1 строка

Поддерживающее утверждение 3: Выбор данных из таблицы, которые необходимо обновить.

Select * from RPT_EMAIL_CATEGORY_PREFERENCE;

Выбрано 34 строки.

По-моему, только 1 строка должна быть обновлена из таблицы RPT_EMAIL_CATEGORY_PREFERENCE, которая удовлетворяет условию обновления. Я пропустил что-то очень тривиальное здесь?

План запроса:

QUERY PLANTEXT:

Вложенная петля (стоимость = 1.6..1.7 строк = 34 ширина = 113 conf = 51)

l: Таблица последовательного сканирования "RPT_EMAIL_CATEGORY_PREFERENCE" (стоимость = 0.0..0.0 rows = 34 width = 105 conf = 100)

r: Materialize (cost = 0.0..0.0 rows = 1 width = 16 conf = 0)

<pre class="prettyprint linenums"> l: Hash Join (cost=0.0..0.0 rows=1 width=16 conf=51) l: Sequential Scan table "S" (cost=0.0..0.0 rows=1 width=266 conf=80) r: Hash (cost=0.0..0.0 rows=1 width=15 conf=0) l: Sequential Scan table "P" (cost=0.0..0.0 rows=1 width=15 conf=64) </pre>

Версия NZ

[nz @usga-qts-tfam-01 ~] $ nzrev

Версия 7.1.0.2-P2 [Построение 39804]

Заранее спасибо. Вивек

1 ответ

Проблема в том, что вы дважды присоединяетесь к RPT_EMAIL_CATEGORY_PREFERENCE. Вы не можете этого понять, потому что соединение с таблицей, указанной для обновления, неявно.

UPDATE RPT_EMAIL_CATEGORY_PREFERENCE 
-- ^ First reference to RPT_EMAIL_CATEGORY_PREFERENCE (with no alias)
SET CVALIDEMAIL = ROUND(S.new_CVALIDEMAIL,0)
FROM SNAPDATE_YOS S 
-- Which is then joined to SNAPDATE S with NO join criteria, making it a cross join producing
-- 1 x 34 rows
JOIN RPT_EMAIL_CATEGORY_PREFERENCE P ON P.PREFERENCE_ID = S.PREFERENCE_ID 
-- The third join then joins 1 row from RPT_EMAIL_CATEGORY_PREFERENCE with no join criteria
-- other than a WHERE clause which makes the output to 1 x 34 x 1 rows.
-- This is because the RPT_EMAIL_CATEGORY_PREFERENCE when referenced with a different alias
-- is treated as a separate table.
WHERE P.SNAPSHOTDATE = '2014-11-21 00:00:00'
AND P.PREFERENCE_ID = 'Yosemite';

UPDATE Я думаю, что вы хотите:

UPDATE RPT_EMAIL_CATEGORY_PREFERENCE 
SET CVALIDEMAIL = ROUND(SNAPDATE_YOS.new_CVALIDEMAIL,0)
FROM SNAPDATE_YOS
WHERE 
RPT_EMAIL_CATEGORY_PREFERENCE.PREFERENCE_ID = SNAPDATE_YOS.PREFERENCE_ID 
AND RPT_EMAIL_CATEGORY_PREFERENCE.SNAPSHOTDATE = '2014-11-21 00:00:00'
AND PRPT_EMAIL_CATEGORY_PREFERENCE.PREFERENCE_ID = 'Yosemite';

Я удалил псевдонимы для ясности (мнения могут варьироваться в зависимости от того, полезны они или нет в этом случае). Вы должны ссылаться только на таблицу UPDATEd. Для Netezza внутренние соединения в UPDATE неявно определяются предложениями FROM и WHERE.

licensed under cc by-sa 3.0 with attribution.