我有桌子t1
ID NAME AGE GENDER BALANCE
----- ----- --------- ----- ---------
1001 John 10 M 10
1002 Meena 5 F 0
1003 Nikh 11 M 0
1004 divs 7 F 0
1005 neha 4 F 0
从第二行开始,如果Gender为M,则应为Balance(第二行) 年龄(2)+平衡(1)
else Balance(1)-age(2)
最终结构应该像
ID NAME AGE GENDER BALANCE
----- ----- --------- ----- ---------
1001 John 10 M 10
1002 Meena 5 F 5
1003 Nikh 11 M 16
1004 divs 7 F 9
1005 neha 4 F 5
请帮我查询/程序
答案 0 :(得分:3)
这样的事情怎么样?
with sample_data as (select 1001 id, 'John' name, 10 age, 'M' gender, 10 balance from dual union all
select 1002 id, 'Meena' name, 5 age, 'F' gender, 0 balance from dual union all
select 1003 id, 'Nikh' name, 11 age, 'M' gender, 0 balance from dual union all
select 1004 id, 'divs' name, 7 age, 'F' gender, 0 balance from dual union all
select 1005 id, 'neha' name, 4 age, 'F' gender, 0 balance from dual)
select id,
name,
age,
gender,
sum(case when gender = 'F' then -1 * age else age end) over (order by id) balance
from sample_data;
ID NAME AGE GENDER BALANCE
---------- ----- ---------- ------ ----------
1001 John 10 M 10
1002 Meena 5 F 5
1003 Nikh 11 M 16
1004 divs 7 F 9
1005 neha 4 F 5
我猜测第一行的余额(我在这里假设一个id的顺序)是10,因为这是约翰的年龄和他的年龄。男性,而不是一些任意数字。
ETA:以上是上述解决方案的替代方案。我 HIGHLY 建议您针对类似生产的数据量测试所有内容(我使用with子句来模仿一个名为sample_data的表,包含5行,您只需要使用您的表)。这样,您就可以获得应该突出显示场景中性能最佳的方法的时间;希望你的经理不会对事实视而不见(如果他是,那就跑。快跑!)
1)没有分析函数的SQL语句:
with sample_data as (select 1001 id, 'John' name, 10 age, 'M' gender, 10 balance from dual union all
select 1002 id, 'Meena' name, 5 age, 'F' gender, 0 balance from dual union all
select 1003 id, 'Nikh' name, 11 age, 'M' gender, 0 balance from dual union all
select 1004 id, 'divs' name, 7 age, 'F' gender, 0 balance from dual union all
select 1005 id, 'neha' name, 4 age, 'F' gender, 0 balance from dual)
select sd1.id,
sd1.name,
sd1.age,
sd1.gender,
sum(case when sd2.gender = 'F' then -1 * sd2.age else sd2.age end) balance
from sample_data sd1
inner join sample_data sd2 on (sd1.id >= sd2.id)
group by sd1.id,
sd1.name,
sd1.age,
sd1.gender
order by id;
ID NAME AGE GENDER BALANCE
---------- ----- ---------- ------ ----------
1001 John 10 M 10
1002 Meena 5 F 5
1003 Nikh 11 M 16
1004 divs 7 F 9
1005 neha 4 F 5
2)程序(逐行慢行{yawn})方法(不推荐):
create or replace procedure calc_balance1
as
v_balance number := 0;
cursor cur is
with sample_data as (select 1001 id, 'John' name, 10 age, 'M' gender, 10 balance from dual union all
select 1002 id, 'Meena' name, 5 age, 'F' gender, 0 balance from dual union all
select 1003 id, 'Nikh' name, 11 age, 'M' gender, 0 balance from dual union all
select 1004 id, 'divs' name, 7 age, 'F' gender, 0 balance from dual union all
select 1005 id, 'neha' name, 4 age, 'F' gender, 0 balance from dual)
select id,
name,
age,
gender,
balance
from sample_data;
begin
for rec in cur
loop
v_balance := v_balance + case when rec.gender = 'F' then -1 * rec.age
else rec.age
end;
dbms_output.put_line('id = '||rec.id||', name = '||rec.name||', age = '||rec.age||', gender = '||rec.gender||', balance = '||v_balance);
end loop;
end calc_balance1;
/
begin
calc_balance;
end;
/
id = 1001, name = John, age = 10, gender = M, balance = 10
id = 1002, name = Meena, age = 5, gender = F, balance = 5
id = 1003, name = Nikh, age = 11, gender = M, balance = 16
id = 1004, name = divs, age = 7, gender = F, balance = 9
id = 1005, name = neha, age = 4, gender = F, balance = 5
但是,如果您必须为此提出一个程序,我将使用带有分析函数的查询并将其粘贴在引用游标中,例如:
create or replace procedure calc_balance2 (p_refcur out sys_refcursor)
as
begin
open p_refcur for with sample_data as (select 1001 id, 'John' name, 10 age, 'M' gender, 10 balance from dual union all
select 1002 id, 'Meena' name, 5 age, 'F' gender, 0 balance from dual union all
select 1003 id, 'Nikh' name, 11 age, 'M' gender, 0 balance from dual union all
select 1004 id, 'divs' name, 7 age, 'F' gender, 0 balance from dual union all
select 1005 id, 'neha' name, 4 age, 'F' gender, 0 balance from dual)
select id,
name,
age,
gender,
sum(case when gender = 'F' then -1 * age else age end) over (order by id) balance
from sample_data
order by id;
end calc_balance2;
/
我看到你写的程序;我会怎么做呢:
-- mimicking your test_divs table:
create table test_divs as
select 1001 id, 'John' name, 10 age, 'M' gender, 10 balance from dual union all
select 1002 id, 'Meena' name, 5 age, 'F' gender, 0 balance from dual union all
select 1003 id, 'Nikh' name, 11 age, 'M' gender, 0 balance from dual union all
select 1004 id, 'divs' name, 7 age, 'F' gender, 0 balance from dual union all
select 1005 id, 'neha' name, 4 age, 'F' gender, 0 balance from dual;
create or replace procedure t1_d12_v2
as
begin
merge into test_divs tgt
using (select id,
name,
age,
gender,
sum(case when gender = 'F' then -1 * age else age end) over (order by id) balance
from test_divs) src
on (tgt.id = src.id)
when matched then
update set tgt.balance = src.balance;
end t1_d12_v2;
/
select * from test_divs;
ID NAME AGE GENDER BALANCE
---------- ----- ---------- ------ ----------
1001 John 10 M 10
1002 Meena 5 F 0
1003 Nikh 11 M 0
1004 divs 7 F 0
1005 neha 4 F 0
begin
t1_d12_v2;
commit;
end;
/
select * from test_divs;
ID NAME AGE GENDER BALANCE
---------- ----- ---------- ------ ----------
1001 John 10 M 10
1002 Meena 5 F 5
1003 Nikh 11 M 16
1004 divs 7 F 9
1005 neha 4 F 5
我 HIGHLY 建议您使用类似生产的数据测试这两种方法,看看哪种方法效果更好。 (如果您的经理真的死于分析函数,我会将" src"子查询交换为我想出的另一个sql语句 - 具有join和group by的那个。)
像你一样逐行地进行更新,每次通过循环都会在sql和pl / sql之间进行两次上下文切换。当你可以在一个sql语句中完成整个事情时,为什么还要烦恼呢。严重。
答案 1 :(得分:0)
select ID, NAME, AGE, GENDER, @b:=if(GENDER='M', @b+AGE, @b-AGE) BALANCE
from t1, (select @b:=0) b
答案 2 :(得分:0)
public static void main(String args[]) throws FileNotFoundException {
Properties ps =new Properties();
// Create the file object
File fileObj = new File("data.txt");
try {
FileInputStream fis = new FileInputStream(fileObj);
ps.load(fis);
System.out.println("Properties:"+ps);
System.out.println("Get A:"+ps.getProperty("a"));
} catch (Exception err) {
err.printStackTrace();
}
}