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

时间:2013-10-09 16:21:43

标签: sql oracle oracle11g

你好我需要一点帮助编写一个sql语句,它基本上会指出没有相应的负匹配数字的行,基于my_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,大多数正数都有直接的负数。另一方面,我需要通过my_id和report_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');

3 个答案:

答案 0 :(得分: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;

这只是给amt 100行的输出行。我已经要求你在注释中澄清为什么应该包含200行(如果应该)。我也不确定你是否想要包含其中一个47.17值。这样做的难点在于您提供的示例数据中两个正值是否相同,这是正确的吗?

答案 1 :(得分: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 AMOUNT MY_ID基金组织

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

答案 2 :(得分:1)

修改

这是基于反馈和提供的其他样本数据的更新查询。此查询的优点是只查询一次TEST表,并返回预期结果(金额为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


INITIAL ANSWER:

以下查询应提供您要查找的内容。我不确定如果组织和/或基金不同,应该怎么做,因为你没有对这些值进行分组 - 我决定在基金和组织上使用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(2)和my_id(910)对应的-200。