1
0匹配的所有行我有两个表:更新一个表中谁拥有1场,超过1场,或在其他表
CREATE TABLE huge ( id INT PRIMARY KEY, name VARCHAR2(100), day INT, errno INT, error_message VARCHAR2(100) ); CREATE TABLE smallish ( id INT PRIMARY KEY, name VARCHAR2(100), day int ); -- Note the lack of a foreign key between huge and smallish on name -- This is intentional
我想要做的三件事情:
- 更新
huge
中的所有行,将day
设置为smallish
中的行,其中huge
中的行恰好有一个name
,位于smallish
中。 - 更新在
huge
所有行有1
一个errno
和:name not in smallish
的error_message
其中huge
行不smallish
有一个名字。 - 更新在
huge
所有行有2
一个errno
和:name has multiple rows in smallish
的error_message
其中huge
行有一个以上的name
在smallish
我用下面的DML的这似乎工作,但其中两个在输出中给出了全表扫描,否则看起来不直观。
此外,在一个声明中完成这一切将是非常酷的,而不是三次。
更新:
以下似乎工作,看起来有点直观,但解释计划显示了巨大的全表扫描:
UPDATE huge h_out SET (day, errno, error_message) = ( select CASE WHEN DAY IS NOT NULL AND count = 1 THEN day ELSE NULL END as bill_day, CASE WHEN day IS NULL THEN 1 WHEN count > 1 THEN 2 ELSE NULL END AS errno, CASE WHEN day IS NULL THEN name || ' not in smallish' WHEN count > 1 THEN name || ' has multiple rows in smallish' ELSE NULL END as error_message FROM ( select dhuge.name, max(smallish.day) as day, count(dhuge.name) as count from (select distinct huge.name from huge) dhuge left join smallish on dhuge.name = smallish.name group by dhuge.name ) h_in WHERE h_out.name = h_in.name );
原文:
-- Problem #1 UPDATE huge h SET (day) = ( SELECT MIN(day) FROM smallish s WHERE h.name = s.name GROUP BY s.name HAVING count(1) = 1 ) WHERE EXISTS ( SELECT null FROM smallish s WHERE s.name = h.name ); -- Problem #2 Explain plan shows a full table scan on huge UPDATE huge h_out SET (errno, error_message) = ( select 1, h_out.name || ' not in smallish' AS error_message FROM DUAL ) WHERE NOT EXISTS ( SELECT NULL FROM smallish s WHERE s.name = h_out.name ); -- Problem #3 Explain plan shows a full table scan on huge UPDATE huge h SET (errno, error_message) = ( SELECT 2, h.name || ' has multiple rows' FROM dual ) WHERE EXISTS ( SELECT s.name FROM smallish s WHERE h.name = s.name GROUP BY s.name HAVING count(1) > 1 );
复制:
DROP TABLE huge; DROP TABLE smallish; CREATE TABLE huge ( id INT PRIMARY KEY, name VARCHAR2(100), day INT, errno INT, error_message VARCHAR2(100) ); CREATE TABLE smallish ( id INT PRIMARY KEY, name VARCHAR2(100), day int ); create index huge_name_indx ON huge (name); create index smallish_name_indx ON smallish (name); insert into huge values (1, 'good1', null, 0, null); insert into huge values (2, 'good1', null, 0, null); insert into huge values (3, 'good1', null, 0, null); insert into huge values (4, 'good1', null, 0, null); insert into huge values (5, 'good2', null, 0, null); insert into huge values (6, 'good2', null, 0, null); insert into huge values (7, 'good2', null, 0, null); insert into huge values (8, 'good2', null, 0, null); insert into huge values (9, 'double1', null, 0, null); insert into huge values (10, 'double1', null, 0, null); insert into huge values (11, 'double1', null, 0, null); insert into huge values (12, 'double1', null, 0, null); insert into huge values (13, 'double2', null, 0, null); insert into huge values (14, 'double2', null, 0, null); insert into huge values (15, 'double2', null, 0, null); insert into huge values (16, 'double2', null, 0, null); insert into huge values(17, 'notin1', null, 0, null); insert into huge values(18, 'notin1', null, 0, null); insert into huge values(19, 'notin1', null, 0, null); insert into huge values(20, 'notin1', null, 0, null); insert into huge values(21, 'notin2', null, 0, null); insert into huge values(22, 'notin2', null, 0, null); insert into huge values(23, 'notin2', null, 0, null); insert into huge values(24, 'notin2', null, 0, null); insert into smallish values (1, 'good1', 1); insert into smallish values (2, 'good2', 2); insert into smallish values (3, 'double1', 3); insert into smallish values (4, 'double1', 4); insert into smallish values (5, 'double2', 5); insert into smallish values (6, 'double2', 6); commit;
在Oracle中,这似乎是给因为使用'update'的错误两次。蟾蜍说'发现'更新'期待'插入'。有任何想法吗? –
我想你打算在括号中包含'h.name - s.name',并在匹配的error_message的case语句中包含'END'。 –
有多少行很大;以及有多少行正在更新? – BobC