Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有联合求精的SQL查询_Sql_Oracle11g_Union - Fatal编程技术网

具有联合求精的SQL查询

具有联合求精的SQL查询,sql,oracle11g,union,Sql,Oracle11g,Union,我想知道是否有更好的方法来编码以下要求: 我正在使用Oracle11.xDB 表格设置: create table S_ASSET (ROW_ID varchar2(10), X_QUOTE_ID varchar2(10), SP_NUM varchar2(10), AMT number(10), ASSET_NUM varchar2(10)); create table S_QUOTE_ITEM (ROW_ID varchar2(10), AMT number(10)); create tab

我想知道是否有更好的方法来编码以下要求: 我正在使用Oracle11.xDB

表格设置:

create table S_ASSET (ROW_ID varchar2(10), X_QUOTE_ID varchar2(10), SP_NUM varchar2(10), AMT number(10), ASSET_NUM varchar2(10));
create table S_QUOTE_ITEM (ROW_ID varchar2(10), AMT number(10));
create table S_QUOTE_ITEM_XM (PAR_ROW_ID varchar2(10), AMT number(10));
表1-

insert into S_ASSET (ROW_ID, X_QUOTE_ID, SP_NUM, AMT, ASSET_NUM) values ('1', 'A1', '000', 10, 'AAA');
insert into S_ASSET (ROW_ID, X_QUOTE_ID, SP_NUM, AMT, ASSET_NUM) values ('1', 'A2', '000', 20, 'AAA');
insert into S_ASSET (ROW_ID, X_QUOTE_ID, SP_NUM, AMT, ASSET_NUM) values ('2', 'B1', '111', '', 'BBB');
insert into S_ASSET (ROW_ID, X_QUOTE_ID, SP_NUM, AMT, ASSET_NUM) values ('3', 'C1', '222', 10, 'CCC');
insert into S_ASSET (ROW_ID, X_QUOTE_ID, SP_NUM, AMT, ASSET_NUM) values ('3', 'C2', '222', 0, 'CCC');
insert into S_ASSET (ROW_ID, X_QUOTE_ID, SP_NUM, AMT, ASSET_NUM) values ('4', 'D1', '333', 10, 'DDD');
insert into S_ASSET (ROW_ID, X_QUOTE_ID, SP_NUM, AMT, ASSET_NUM) values ('5', 'E1', '444', 0, 'EEE');
表2-

insert into S_QUOTE_ITEM (ROW_ID, AMT) values ('A1', 5);
insert into S_QUOTE_ITEM (ROW_ID, AMT) values ('A2', '');
insert into S_QUOTE_ITEM (ROW_ID, AMT) values ('B1', 0);
insert into S_QUOTE_ITEM (ROW_ID, AMT) values ('C1', 5);
insert into S_QUOTE_ITEM (ROW_ID, AMT) values ('C2', 0);
insert into S_QUOTE_ITEM (ROW_ID, AMT) values ('D1', '');
insert into S_QUOTE_ITEM (ROW_ID, AMT) values ('E1', 5);
表3-

insert into S_QUOTE_ITEM_XM (PAR_ROW_ID, AMT) values ('A1', 1);
insert into S_QUOTE_ITEM_XM (PAR_ROW_ID, AMT) values ('A1', '');
insert into S_QUOTE_ITEM_XM (PAR_ROW_ID, AMT) values ('B1', 1);
其中x-quote_id(表1的)=行_id(表2的)=部分行_id(表3的)

我需要按sp_num分组的AMT列的总和。下面是我编写的查询。我正在寻找一种更短更有效的方法来写同样的东西

select sp_num, sum(amt) as DocFee
from
(   
    (
        select x_quote_id row_id, amt, sp_num
        from s_asset
    )
    union
    (   
        select a.row_id, a.amt, b.sp_num
        from
        (   
            select row_id, sum(amt) amt
            from s_quote_item
            group by row_id
        ) a,
        s_asset b
        where b.x_quote_id = a.row_id
    )
    union      
    (
        select a.par_row_id row_id, a.amt, b.sp_num
        from
        (
            select par_row_id, sum(amt) amt
            from s_quote_item_xm
            group by par_row_id
        ) a,
        s_asset b
        where b.x_quote_id = a.par_row_id
    )
)
group by sp_num 
order by sp_num
预期O/p:

sp_num    DocFee
000       36
111       1
222       15
333       10
444       5
感谢所有提出高效解决方案的人。然而,我很难将下面的查询组合起来(因为我是一个全新的SQL),所有这些查询都有一个公共因子sp_num

问题1:(家长)

问题2:(GP)

查询3:(DOCFEE)(以下内容或Juan Carlos在此线程中共享的结果)


我认为最好在
sp_num
级别聚合每个子表,然后进行最终聚合:

select sp_num, sum(amt)
from ((select a.sp_num, sum(a.amt) as amt
       from s_asset a
       group by a.sp_num
      ) union all
      (select a.sp_num, sum(q.amt) as amt
       from s_asset a join
            s_quote_item q
            on q.row_id = a.x_quote_id
       group by a.sp_num
      ) union all
      (select a.sp_num, sum(x.amt) as amt
       from s_asset a join
            s_quote_item_xm x
            on x.par_row_id = a.x_quote_id
       group by a.sp_num
      )
     ) aqx
group by sp_num;
如果愿意,可以通过删除第一级聚合来缩短查询:

select sp_num, sum(amt)
from ((select a.sp_num, a.amt as amt
       from s_asset a
      ) union all
      (select a.sp_num, q.amt as amt
       from s_asset a join
            s_quote_item q
            on q.row_id = a.x_quote_id
      ) union all
      (select a.sp_num, x.amt as amt
       from s_asset a join
            s_quote_item_xm x
            on x.par_row_id = a.x_quote_id
      )
     ) aqx
group by sp_num;
我的猜测是,在大多数情况下,Oracle会为第一个版本制定更好的执行计划。

WITH A as (
     SELECT sp_num, X_QUOTE_ID, sum(AMT) AMT
     FROM S_ASSET
     GROUP BY sp_num, X_QUOTE_ID
), B as (
     SELECT ROW_ID, sum(AMT) AMT
     FROM S_QUOTE_ITEM
     GROUP BY ROW_ID
), C as (
     SELECT PAR_ROW_ID, sum(AMT) AMT
     FROM S_QUOTE_ITEM_XM
     GROUP BY PAR_ROW_ID  
)
SELECT sp_num, COALESCE(SUM(A.AMT),0) + 
               COALESCE(SUM(B.AMT),0) + 
               COALESCE(SUM(C.AMT),0) DOCFEE
FROM A
LEFT JOIN B
       ON A.X_QUOTE_ID = B.ROW_ID
LEFT JOIN C
       ON A.X_QUOTE_ID = C.PAR_ROW_ID
GROUP BY sp_num     
ORDER BY sp_num;

谢谢Gordon,我不熟悉Oracles的执行方式,它只是想减少代码行并确保bext性能。谢谢Juan Carlos。我有点被“加入”的概念吓坏了…因此尽可能避免它。但在完成代码时,我会记住这一点。这证明了编写SQL查询的方法不止一种。你可以让我知道;如果我将这个查询与另外两个都将sp_num作为公共因子的查询结合起来,您将如何处理它。。。我已经附加了上面的其他查询线程…再次感谢你可以看到我已经在这里做了。我用
B
C
加入
A
。我更喜欢cte符号,因为它易于阅读。如果你把你的问题分成小块,然后加入其中,也很容易together@AnnaJoel . . . 在您的情况下,这比我的答案中的聚合方法快吗?@GordonLinoff我知道这是一个小样本,但我将原始解决方案和我们的两个答案都放在了sqlFiddle上。因此,请检查解释计划。使用Oracle 11.x…。希望您能抽出几分钟时间,帮助我解决更多问题,在本例中,我在本线程中添加了相同的内容,如果您创建一个新问题并链接到此问题,效果会更好。另外,我看不出您的新请求的预期输出是什么。我没有看到新表的模式。您还可以在中创建模式,以提供一个很好的工具来生成/测试查询
select sp_num, sum(amt)
from ((select a.sp_num, sum(a.amt) as amt
       from s_asset a
       group by a.sp_num
      ) union all
      (select a.sp_num, sum(q.amt) as amt
       from s_asset a join
            s_quote_item q
            on q.row_id = a.x_quote_id
       group by a.sp_num
      ) union all
      (select a.sp_num, sum(x.amt) as amt
       from s_asset a join
            s_quote_item_xm x
            on x.par_row_id = a.x_quote_id
       group by a.sp_num
      )
     ) aqx
group by sp_num;
select sp_num, sum(amt)
from ((select a.sp_num, a.amt as amt
       from s_asset a
      ) union all
      (select a.sp_num, q.amt as amt
       from s_asset a join
            s_quote_item q
            on q.row_id = a.x_quote_id
      ) union all
      (select a.sp_num, x.amt as amt
       from s_asset a join
            s_quote_item_xm x
            on x.par_row_id = a.x_quote_id
      )
     ) aqx
group by sp_num;
WITH A as (
     SELECT sp_num, X_QUOTE_ID, sum(AMT) AMT
     FROM S_ASSET
     GROUP BY sp_num, X_QUOTE_ID
), B as (
     SELECT ROW_ID, sum(AMT) AMT
     FROM S_QUOTE_ITEM
     GROUP BY ROW_ID
), C as (
     SELECT PAR_ROW_ID, sum(AMT) AMT
     FROM S_QUOTE_ITEM_XM
     GROUP BY PAR_ROW_ID  
)
SELECT sp_num, COALESCE(SUM(A.AMT),0) + 
               COALESCE(SUM(B.AMT),0) + 
               COALESCE(SUM(C.AMT),0) DOCFEE
FROM A
LEFT JOIN B
       ON A.X_QUOTE_ID = B.ROW_ID
LEFT JOIN C
       ON A.X_QUOTE_ID = C.PAR_ROW_ID
GROUP BY sp_num     
ORDER BY sp_num;