如何在没有分组的情况下向 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;
这是我的问题,我正在处理现有的大型报告,他们希望我在每次数据库中的行满足条件时添加具有特定值的虚构行(假设状态 = 已取消) 我将查询(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;