如何在没有分组的情况下向 Oracle 中的 SQL 结果添加虚构行

How to add fictional rows to an SQL results in Oracle without à grouping

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

如果我有两个 table A 和 B :

Table A
Name            Status              Estimated       Real  
COMPANY A       Completed           .00          .00   
COMPANY B       Canceled            [=11=].00           [=11=].00  
COMPANY C       Not Approved        0.00     [=11=].00  
COMPANY D       Withdrawn           .00          .00   
COMPANY E       Not Approved        [=11=].00           [=11=].00  
COMPANY F       Canceled            ,000.00       ,000.00
---------------------------------------------------------------

Table B
Name            Status              Estimated       Real  
COMPANY G       In Progress         .00          .00   
COMPANY H       Not Started         .00          [=11=].00  
COMPANY H       Passed              0.00     0.00  
COMPANY I       Approved            .00          [=11=].00   
COMPANY J       Canceled            .00          .00  
COMPANY A       Scheduled           ,000.00       ,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           .00          .00   
COMPANY A       Scheduled           ,000.00       ,000.00
COMPANY B       Canceled            [=13=].00           [=13=].00  
COMPANY C       Not Approved        0.00     [=13=].00  
COMPANY D       Withdrawn           .00          .00   
COMPANY E       Not Approved        [=13=].00           [=13=].00  
COMPANY F       Canceled            ,000.00       ,000.00
COMPANY G       In Progress         .00          .00   
COMPANY H       Not Started         .00          [=13=].00  
COMPANY H       Passed              0.00     0.00  
COMPANY I       Approved            .00          [=13=].00   
COMPANY J       Canceled            .00          .00  

现在我需要做的是在状态被取消时插入虚构的行: 对于 Status = Canceled 的每一行,添加具有相同名称和估计列的行,Status Scheduled 和 Real = 0。结果应该如下所示:(我在虚构的行之前添加了 **)

Name            Status              Estimated       Real  
COMPANY A       Completed           .00          .00   
COMPANY A       Scheduled           ,000.00       ,000.00
COMPANY B       Canceled            [=14=].00           [=14=].00  
**COMPANY B     Scheduled           [=14=].00           [=14=].00**  
COMPANY C       Not Approved        0.00     [=14=].00  
COMPANY D       Withdrawn           .00          .00   
COMPANY E       Not Approved        [=14=].00           [=14=].00  
COMPANY F       Canceled            ,000.00       ,000.00
**COMPANY F     Scheduled           ,000.00       [=14=].00**
COMPANY G       In Progress         .00          .00   
COMPANY H       Not Started         .00          [=14=].00  
COMPANY H       Passed              0.00     0.00  
COMPANY I       Approved            .00          [=14=].00   
COMPANY J       Canceled            .00          .00  
**COMPANY J     Scheduled           .00          [=14=].00**

我尝试使用 dual 连接或 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 行)
  • 获取应成为 "scheduled" 的取消名称(第 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 虚构的行并与您现有的结果集合并。

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;