oracle sql如何获取不匹配的正记录

oracle sql如何获取不匹配的正记录,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,大家好,我需要一些帮助来编写一个sql语句,根据我的id,report id,该语句基本上可以指出没有相应的负匹配号的行 以下是表格声明,以便更好地解释 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)

大家好,我需要一些帮助来编写一个sql语句,根据我的id,report id,该语句基本上可以指出没有相应的负匹配号的行

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

   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,大多数正金额都有一个直接的负金额。另一方面,我需要通过我的_id识别那些没有相应的负金额的正金额,并报告_id

预期结果应该是这样的

"REPORT_ID"                   "FUND"                        "MY_ID"                       "ORG"                         "AMOUNT"                      
"1"                           "100000"                      "910"                         "67150"                       "40.17"                       
"1"                           "100000"                      "910"                         "67150"                       "100"                         
有什么办法可以做到这一点

编辑: 发布了错误的输出结果。只是想澄清一下,在比赛结束之前,基金和组织并不重要。例如,如果我用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');

新版本

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;
这应该只返回您想要的行。如果您不关心组织或基金,则可以使用别名为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;

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

一个修改过的版本查询,适用于您的场景。我使用了SQLServerz

   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;
结果与您的数据 申报ID金额我的ID基金组织

1   100 910 100000  67150
运行此更新查询后的结果
更新测试集AMOUNT=-500,其中AMOUNT=-200

REPORT_ID   AMOUNT  MY_ID   FUND    ORG
1   100 910 100000  67150
2   -500    910 100000  67120
2   200 910 100000  67130
编辑:

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');
下面是一个基于反馈和提供的其他示例数据的更新查询。此查询的优点是只查询一次测试表,并返回预期结果(3行amount 71、1行amount 100和1行amount 40.17)

结果:

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
report_id    fund    my_id    org    amount
1            100000  910      67150  40.17
1            100000  910      67150  100.00

初始答案:

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');
下面的查询应该提供您要查找的内容。我不确定如果组织和/或基金不同,应该怎么做,因为您没有根据这些值进行分组-我决定在基金和组织上使用最大聚合函数来选择单个值,而不影响分组。也许那些专栏应该被忽略掉

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
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
report_id    fund    my_id    org    amount
1            100000  910      67150  40.17
1            100000  910      67150  100.00

请注意,根据您提供的示例数据,预期结果不应显示为200,因为同一报告id(2)和我的id(910)对应一个-200。

非常令人耳目一新,所有数据都可以在问题中使用!请您澄清一下,为什么上面的输出中显示了200,因为有一个对应的-200行?组织如何?应该忽略这一点吗?回答以上两条评论,人们就会给你一些问题。@miguel:你是说在一组report\u id和my\u id中,如果发现任何数量为负数的记录,就会过滤该组吗?或者只需要过滤负数?@chris 200在那里,因为没有其他200具有相同的my_id、report_id、negative AmountAmountAmount=-200不应该出现在基于您的数据的结果中,因为它具有相同的report_id和my_id以及200和-200作为amout。这将被查询丢弃。这是正确的,我应该以40.17结束,因为有两个一个pos和一个neg。两个然后相互抵消,因此一个肯定的结果应该出来。我刚刚用编辑更新了你一直都是对的,我很抱歉我是个白痴。@Miguel别担心,会出错的。chris这很接近答案。我将添加由于某种原因导致此操作失败的附加insert语句。如果我添加以下insert语句,它会拾取过多的71?我预计有371个会回来,但其中4个会回来。有什么想法吗?肖恩,你是对的,这很接近,但我需要得到资金和组织的不匹配的项目已经匹配。因此max org不会为我工作。想象一下,如果你有两张纸,一张是负数,另一张是正数。你可以使用一个高升和高亮度的灯,严格根据正负值的大小来决定。一旦你完成了,你会留下一些积极的数额和额外的数据。这就是我所要完成的。@米格尔-考虑以下数据:
BR/> <代码> RePortId基金MyOID ID ORG量1 100000 67150 910 60 1 100000 100000 910 67151 -60.00 1 100000 910 910 < /代码> BR/> BR/>我们将显示一个量。我们应该展示哪个组织?67150或67152?很抱歉,我错过了你要发布数据的地方吗?@Miguel-是的-这里的评论格式有点问题。希望这一次能奏效。

考虑以下数据:

报告我的id基金我的id组织金额100000 910 67150 60.00 100000 910 67151-60.00 100000 910 67152 60.00

。我们应该展示哪个组织?67150还是67152?两者都不重要。但是想想看,在60岁以上的人中有6个,只有一个-60岁。只有一个60位匹配,只有一个60位负匹配,我应该看到剩下的5行。我们匹配到哪一行并不重要,但重要的是我们看到剩余的“不匹配”行