如何在不进行分组的情况下在Oracle中向SQL结果添加虚拟行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在不进行分组的情况下在Oracle中向SQL结果添加虚拟行相关的知识,希望对你有一定的参考价值。

这是我的问题,我正在处理一个现有的大型报告,他们希望我每次数据库中的行满足条件时都添加具有特定值的虚拟行(假设状态=已取消)我将查询(SQL代码的1000行)简化为::>

如果我有两个表A和B:

Table A
Name            Status              Estimated       Real  
COMPANY A       Completed           $50.00          $50.00   
COMPANY B       Canceled            $0.00           $0.00  
COMPANY C       Not Approved        $100.00     $0.00  
COMPANY D       Withdrawn           $20.00          $10.00   
COMPANY E       Not Approved        $0.00           $0.00  
COMPANY F       Canceled            $1,000.00       $1,000.00
---------------------------------------------------------------

Table B
Name            Status              Estimated       Real  
COMPANY G       In Progress         $50.00          $20.00   
COMPANY H       Not Started         $20.00          $0.00  
COMPANY H       Passed              $100.00     $100.00  
COMPANY I       Approved            $20.00          $00.00   
COMPANY J       Canceled            $14.00          $6.00  
COMPANY A       Scheduled           $2,000.00       $2,000.00

查询就是这样:

SELECT * from (
SELECT NAME,STATUS,ESTIMATED,REAL from A
UNION ALL
SELECT NAME,STATUS,ESTIMATED,REAL from B
) order by name

结果是这样的:

Name            Status              Estimated       Real  
COMPANY A       Completed           $50.00          $50.00   
COMPANY A       Scheduled           $2,000.00       $2,000.00
COMPANY B       Canceled            $0.00           $0.00  
COMPANY C       Not Approved        $100.00     $0.00  
COMPANY D       Withdrawn           $20.00          $10.00   
COMPANY E       Not Approved        $0.00           $0.00  
COMPANY F       Canceled            $1,000.00       $1,000.00
COMPANY G       In Progress         $50.00          $20.00   
COMPANY H       Not Started         $20.00          $0.00  
COMPANY H       Passed              $100.00     $100.00  
COMPANY I       Approved            $20.00          $00.00   
COMPANY J       Canceled            $14.00          $6.00  

现在,我需要做的就是在状态取消时插入虚构的行,如下所示:对于状态=已取消的每一行,添加具有相同名称和估计列的行,状态已计划且实数=0。结果应类似于:(我在虚构行之前添加了**)

Name            Status              Estimated       Real  
COMPANY A       Completed           $50.00          $50.00   
COMPANY A       Scheduled           $2,000.00       $2,000.00
COMPANY B       Canceled            $0.00           $0.00  
**COMPANY B     Scheduled           $0.00           $0.00**  
COMPANY C       Not Approved        $100.00     $0.00  
COMPANY D       Withdrawn           $20.00          $10.00   
COMPANY E       Not Approved        $0.00           $0.00  
COMPANY F       Canceled            $1,000.00       $1,000.00
**COMPANY F     Scheduled           $1,000.00       $0.00**
COMPANY G       In Progress         $50.00          $20.00   
COMPANY H       Not Started         $20.00          $0.00  
COMPANY H       Passed              $100.00     $100.00  
COMPANY I       Approved            $20.00          $00.00   
COMPANY J       Canceled            $14.00          $6.00  
**COMPANY J     Scheduled           $14.00          $0.00**

我尝试使用偶数进行联接或UNION,但是我不知道缺少什么。非常感谢]]

这是我的问题,我正在处理一个现有的大报告,他们希望我每次数据库中的行满足条件时就添加具有特定值的虚拟行(假设状态=已取消)... ...>

with子查询中简单使用您的查询

with tab as (
SELECT * from (
SELECT "Name","Status" ,"Estimated","Real" from A
UNION ALL
SELECT "Name","Status" ,"Estimated","Real" from B
)
)
select * from tab

并从同一源添加新的UNION ALL查询,仅过滤cancelled行并根据需要管理列:

with tab as (
SELECT * from (
SELECT "Name","Status" ,"Estimated","Real" from A
UNION ALL
SELECT "Name","Status" ,"Estimated","Real" from B
)
)
select * from tab
union all
select "Name", 'Scheduled', "Estimated", 0 "Real"
from tab where "Status" = 'Canceled';

请注意,real不是列名的最佳选择,因为它是保留字

,所以我必须将其用双引号引起来。
  • 示例数据从第1行到第13行
  • 工会(您已经有)是tabunion CTE(第14-18行)
  • 获取应该变成“预定的”已取消的名称(第20-24行)
  • 最终结果是另一个联合

  • SQL> with
      2  taba (name, status, estimated, real) as
      3    (select 'A', 'completed'   ,   50,   50 from dual union all
      4     select 'B', 'canceled'    ,    0,    0 from dual union all
      5     select 'C', 'not approved',  100,    0 from dual union all
      6     select 'F', 'canceled'    , 1000, 1000 from dual
      7    ),
      8  tabb (name, status, estimated, real) as
      9    (select 'G', 'in progress',   50,   20 from dual union all
     10     select 'I', 'approved'   ,   20,    0 from dual union all
     11     select 'J', 'canceled'   ,   14,    6 from dual union all
     12     select 'A', 'scheduled'  , 2000, 2000 from dual
     13    ),
     14  tabunion as
     15    (select name, status, estimated, real from taba
     16     union all
     17     select name, status, estimated, real from tabb
     18    ),
     19  -- canceled statuses that should become "scheduled"
     20  canc as
     21    (select name, 'scheduled' status, estimated, 0 real
     22     from tabunion
     23     where status = 'canceled'
     24    )
     25  -- for final result, union A, B and CANC
     26  select name, status, estimated, real
     27    from tabunion
     28  union all
     29  select name, status, estimated, real
     30    from canc
     31  order by name;
    
    N STATUS        ESTIMATED       REAL
    - ------------ ---------- ----------
    A completed            50         50
    A scheduled          2000       2000
    B canceled              0          0
    B scheduled             0          0
    C not approved        100          0
    F canceled           1000       1000
    F scheduled          1000          0
    G in progress          50         20
    I approved             20          0
    J scheduled            14          0
    J canceled             14          6
    
    11 rows selected.
    
    SQL>
     

    您可以尝试一下,请注意,C是一个内联视图,用于选择虚构的行并与您现有的结果集进行并集。

    SELECT * 
    FROM   (SELECT C.name, 
                   'Scheduled' AS status, 
                   0           AS estimated, 
                   0           AS real 
            FROM   (SELECT name, 
                           status 
                    FROM   a 
                    UNION ALL 
                    SELECT name, 
                           status 
                    FROM   b) C 
            WHERE  C.status = 'Canceled') 
    UNION ALL 
    (SELECT name, 
            status, 
            estimated, 
            real 
     FROM   a 
     UNION ALL 
     SELECT name, 
            status, 
            estimated, 
            real 
     FROM   b) 
    ORDER  BY name, 
              estimated DESC; 
    
    答案

    with子查询中简单使用您的查询

    另一答案
    • 示例数据从第1行到第13行
    • 工会(您已经有)是tabunion CTE(第14-18行)
    另一答案

    您可以尝试一下,请注意,C是一个内联视图,用于选择虚构的行并与您现有的结果集进行并集。

    SELECT * 
    FROM   (SELECT C.name, 
                   'Scheduled' AS status, 
                   0           AS estimated, 
                   0           AS real 
            FROM   (SELECT name, 
                           status 
                    FROM   a 
                    UNION ALL 
                    SELECT name, 
                           status 
                    FROM   b) C 
            WHERE  C.status = 'Canceled') 
    UNION ALL 
    (SELECT name, 
            status, 
            estimated, 
            real 
     FROM   a 
     UNION ALL 
     SELECT name, 
            status, 
            estimated, 
            real 
     FROM   b) 
    ORDER  BY name, 
              estimated DESC; 
    

    以上是关于如何在不进行分组的情况下在Oracle中向SQL结果添加虚拟行的主要内容,如果未能解决你的问题,请参考以下文章

    如何在不使用 GROUP BY 或 PARTITION BY 的情况下对 Oracle SQL 中的数据进行分组

    SQL (Oracle):按特定列分组

    如何在不使用数据透视和反透视的情况下在 SQL Server 中水平显示数据?

    如何在不插入值的情况下在sql中创建动态行?

    如何在不使用 SQL Server/MS Access 的所有选定列的情况下进行分组和求和?

    如何在不使用pivot和unpivot的情况下在SQL Server中水平显示数据?