2

大家好,我需要一些帮助来编写一个 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');
4

3 回答 3

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 值之一。这样做的困难在于您提供的示例数据中的两个正值是相同的,这是正确的吗?

于 2013-10-09T16:46:49.823 回答
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 FUND 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
于 2013-10-09T16:54:14.363 回答
1

编辑:

这是基于反馈和提供的其他示例数据的更新查询。该查询的优点是只查询了TEST表一次,并且返回了预期的结果(3行金额71,1行金额100,1行金额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


初步答案:

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

于 2013-10-09T19:18:44.210 回答