2013-10-09 41 views
2

你好我需要一点帮助,编写一个基于my_id,report_id基本上指出没有相应的否定匹配数的行的sql语句。oracle sql如何获得不匹配的积极记录

下面是表格声明,以便更好地解释。

CREATE TABLE ."TEST" 
    ("REPORT_ID" VARCHAR2(100 BYTE), 
"AMOUNT" NUMBER(17,2), 
"MY_ID" VARCHAR2(30 BYTE), 
"FUND" VARCHAR2(20 BYTE), 
"ORG" VARCHAR2(20 BYTE) 
    ) 

这里是一些样本数据

Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('1',50,'910','100000','67120'); 

Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('1',-50,'910','100000','67130'); 

Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('1',100,'910','100000','67150'); 

Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('2',200,'910','100000','67130'); 

Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('2',-200,'910','100000','67120'); 
INSERT INTO TEST (REPORT_ID, AMOUNT, MY_ID, FUND, ORG) VALUES ('1', '40.17', '910', '100000', '67150') 
INSERT INTO TEST (REPORT_ID, AMOUNT, MY_ID, FUND, ORG) VALUES ('1', '-40.17', '910', '100000', '67150') 
INSERT INTO TEST (REPORT_ID, AMOUNT, MY_ID, FUND, ORG) VALUES ('1', '40.17', '910', '100000', '67150') 
如果你创建表并仔细观察

,你会发现,通过REPORT_ID和添加my_id最积极的数量有直接的负面量。另一方面,我需要通过my_id和report_id来确定那些没有相应负值的正数。

预期的结果应该是这样的

"REPORT_ID"     "FUND"      "MY_ID"      "ORG"       "AMOUNT"      
"1"       "100000"      "910"       "67150"      "40.17"      
"1"       "100000"      "910"       "67150"      "100"       

任何想法如何能acomplish这一点。

编辑: 发布了错误的输出结果。只是为了清楚基金和组织直到比赛结束后才有意义。例如,如果我正在使用plsql写这个,我会发现有多少缺点,然后我有多少个额外的比较每个加上金额的每个减去金额和删除它们,然后我会留下任何加上没有负金额。 我对此感到抱歉。希望这现在更清楚。一旦我拥有了所有的比赛,我应该只剩下积极的数额。

编辑:

additional inserts 

Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',71,'911','100000','67150'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',71,'911','100000','67120'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',71,'911','100000','67140'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',71,'911','100000','67130'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',71,'911','100000','67130'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',71,'911','100000','67130'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',-71,'911','100000','67150'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',-71,'911','100000','67150'); 
Insert into TEST (REPORT_ID,AMOUNT,MY_ID,FUND,ORG) values ('5',-71,'911','100000','67150'); 
+1

非常令人耳目一新,所有的数据都可以在问题中使用!请你只是澄清为什么200会显示在上面的输出中,因为有相应的-200行? – ChrisProsser

+2

org呢?应该忽略? – mucio

+0

回答以上2条评论,那么人们可以给你一些问题。 – johnny

回答

1

新版本

这应该只返回所需的行。如果你不与组织或基金有关,那么你就只能使用的别名X查询:

select distinct t1.report_id, t1.fund, t1.my_id, t1.org, t1.amount 
    from test t1, 
     (select distinct t.report_id, t.my_id, abs(amount) as amount 
     from test t 
     group by t.report_id, t.my_id, abs(amount) 
     having sum(t.amount) > 0) x 
where t1.report_id = x.report_id 
    and t1.my_id = x.my_id 
    and t1.amount = x.amount; 

以前的版本

select * 
    from test t 
minus 
select t1.* 
    from test t1, 
     test t2 
where t1.amount = -1*t2.amount 
    and t1.report_id = t2.report_id 
    and t1.my_id = t2.my_id; 

这只是给出了输出的行中的一行我已经要求你在评论中澄清为什么应该包含任何200行(如果应该的话)。我也不确定是否需要包含47.17的值中的一个。这样做的困难在于您提供的示例数据中的两个正值是相同的,这是正确的吗?

+0

我澄清以上感谢和抱歉的混淆。 – Miguel

+0

这是正确的,我应该以40.17结束,因为有两个pos和一个neg。然后两个相互抵消,因此单一的积极应该出来。 – Miguel

+0

我刚刚更新了编辑,你一直对我道歉,我是一个白痴。 – Miguel

1

这是一个修改后的版本查询,适用于我的情况。我用SQL SERVERZ

select * 
    from test t 
EXCEPT 
select t1.* 
    from test t1, 
     test t2 
where t1.amount = -1*t2.amount 
    and t1.report_id = t2.report_id 
    and t1.my_id = t2.my_id; 

结果与您的数据 REPORT_ID金额添加my_id基金ORG

1 100 910 100000 67150 

结果运行此更新查询后update test set AMOUNT=-500 where AMOUNT=-200

REPORT_ID AMOUNT MY_ID FUND ORG 
1 100 910 100000 67150 
2 -500 910 100000 67120 
2 200 910 100000 67130 
+0

数量= -200不应该根据您的数据得到结果,因为它具有与200和-200相同的report_id和相同的MY_ID。这将被查询丢弃。 – johnny

1

编辑:

这里是基于反馈和提供的其他示例数据更新后的查询。这个查询的优点是只查询一次TEST表,并返回预期结果(3行71,一行100,一行40.17)。

SELECT 
    report_id, MAX(fund) fund, my_id, MAX(org) org, SUM(amount) amount 
FROM (
    SELECT 
     report_id, fund, my_id, org, amount 
     , ROW_NUMBER() OVER(PARTITION BY report_id, my_id, amount) rn 
    FROM 
     test 
) t 
GROUP BY 
    rn, ABS(amount), report_id, my_id 
HAVING 
    SUM(amount) > 0; 

结果:

report_id fund my_id org amount 
5   100000 911  67120 71.00 
5   100000 911  67140 71.00 
5   100000 911  67150 71.00 
1   100000 910  67150 40.17 
1   100000 910  67150 100.00 


最初的回答:

下面的查询应该提供您要查找的内容。如果组织和/或资金不同,我不确定应该做什么,因为您没有将这些值分组 - 我决定在基金和组织中使用MAX汇总函数来选择单个值,而不影响分组。也许这些专栏应该被排除在外?

SELECT 
    report_id, MAX(fund) fund, my_id, MAX(org) org, SUM(amount) amount 
FROM 
    test 
GROUP BY 
    report_id, my_id, ABS(amount) 
HAVING 
    SUM(amount) > 0; 

结果:

report_id fund my_id org amount 
1   100000 910  67150 40.17 
1   100000 910  67150 100.00 

请注意,根据您提供的样本数据,预期的结果不应该表现出200,因为有对同一REPORT_ID相应-200(2),并添加my_id(910 )。

+0

肖恩你是对的,这是非常接近,但我需要得到的资金和不匹配项目的组织已匹配。因此max org不适合我。试想一下,如果你在一张纸上有两张纸,你会得到一定数量的纸张,而在另一张纸张上则会有额外的数量你会严格地使用高亮度和高亮度来对消极情绪进行消极评估。一旦你完成,你会留下一些积极的数额和额外的数据。这就是我试图在这里完成的。 – Miguel

+0

@Miguel - 请看下面的数据:

'REPORT_ID基金组织添加my_id量 1 100000 910 67150 60.00 1 100000 910 67151 -60.00 1 100000 910 67152 60.00'

我们将表明60.00的量。我们应该展示哪些组织? 67150或67152? –

+0

抱歉,我错过了要发布一些数据的内容吗? – Miguel