【问题标题】:How to add fictional rows to an SQL results in Oracle without à grouping如何在没有 à 分组的情况下将虚构行添加到 Oracle 中的 SQL 结果
【发布时间】:2019-12-26 18:45:40
【问题描述】:

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

如果我有两个表 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  

现在我需要做的是每当状态被取消时插入虚构的行: 对于 Status = Canceled 的每一行,添加一个具有相同 Name 和 Estimated 列、Status Scheduled 和 Real = 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**

我尝试使用双重连接或联合,但我不知道缺少什么。非常感谢

【问题讨论】:

  • 是否有字段给出公司不同状态之间的顺序?或者 Canceled 状态不必是创建虚构行的最后一个状态。

标签: sql oracle reporting


【解决方案1】:

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 不是列名的最佳选择,因为它是一个保留字,所以我必须用双引号将其括起来。

【讨论】:

  • 效果很好,谢谢,现在我要调整这个解决方案来适应我的千行查询,非常感谢
  • @Slifer with 子句 (CTE) 使得编写第 1000 行 union 查询仅一次使用两次成为可能.与accepted 的解决方案相反,您必须在两个地方复制大的union;)
【解决方案2】:

您可以尝试一下,注意 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; 

【讨论】:

    【解决方案3】:
    • 样本数据是从第 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>
    

    【讨论】:

      猜你喜欢
      • 2019-04-09
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      相关资源
      最近更新 更多