1. 程式人生 > >ORA-01427: 單行子查詢返回多個行

ORA-01427: 單行子查詢返回多個行

group by and ont sel where條件 color 解決 subquery sta

有人問題我一個問題,情況如下:
他要用根據divide_act_channel_day的new_amount字段去更新divide_stat的new_amount字段。
兩張表關聯的條件:day=log_time,channel=channel


--SQL如下:
update divide_stat
set divide_stat.new_amount=(select divide_act_channel_day.new_amount from divide_act_channel_day
where divide_stat.day=divide_act_channel_day.log_time
and divide_stat.channel=divide_act_channel_day.channel

);


SQL 錯誤: ORA-01427: 單行子查詢返回多個行
01427. 00000 - "single-row subquery returns more than one row"


--推測子查詢中肯定有返回多行的情況,試著在子查詢中加入rownum<2,也就是限制返回一行數據。成功!
update divide_stat
set divide_stat.new_amount=(select divide_act_channel_day.new_amount from divide_act_channel_day
where divide_stat.day=divide_act_channel_day.log_time
and divide_stat.channel=divide_act_channel_day.channel and rownum<2);


--找出divide_act_channel_day表重復行。有9行重復。
select * from
(
select count(*) total,log_time,channel from divide_act_channel_day
group by log_time, channel
)
where total>1;


TOTAL LOG_TIME CHANNEL
---------------------- ------------------------- --------------------------------------------------
2 2012-12-12 00:00:00 0
2 2012-12-13 00:00:00 0
2 2013-01-07 00:00:00 0
2 2012-12-15 00:00:00 0
2 2012-12-01 00:00:00 0
2 2012-12-31 00:00:00 0
2 2012-12-04 00:00:00 0
2 2012-12-23 00:00:00 0
2 2012-12-21 00:00:00 0

9 所選行


--觀察divide_act_channel_day表,發現它根本沒有重復行。看來是where條件精度不夠造成的行重復。


--觀察divide_act_channel_day和divide_stat兩張表,發現它們還有可以關聯的列:amount和NEW_USER_AMOUNT。
--這樣就沒有重復行了。
select * from
(
select count(*) total,log_time,channel,amount,NEW_USER_AMOUNT from divide_act_channel_day
group by log_time, channel, amount, NEW_USER_AMOUNT
)
where total>1;


no rows selected


--修改upadte語句
update divide_stat
set divide_stat.new_amount=(select divide_act_channel_day.new_amount from divide_act_channel_day
where divide_stat.day=divide_act_channel_day.log_time
and divide_stat.channel=divide_act_channel_day.channel and divide_stat.amount=divide_act_channel_day.amount
and divide_stat.NEW_USER_AMOUNT=divide_act_channel_day.NEW_USER_AMOUNT
);


結論:
1.根據A表的某列去update B表的某列時,一定要找出A B兩張表可以關聯的所有字段,這樣基本上不會出現"ORA-01427: 單行子查詢返回多個行";
2.如果A表中真的有重復行,那就加上rownum<2條件解決。

ORA-01427: 單行子查詢返回多個行