通过 select 语句在 ORACLE SQL 中添加具有空度量的行
Adding rows with null measures in ORACLE SQL by select statment
我想寻求一点帮助。
我有以下数据
Name Date Count
P 01/01/20 4
P 01/03/20 3
P 01/05/20 2
P 01/06/20 5
T 01/12/19 4
T 01/01/20 1
我想在计数字段中添加空行,以获得以下结果
Name Date Count
P 01/12/19 null
P 01/01/20 4
P 01/02/20 null
P 01/03/20 3
P 01/04/20 null
P 01/05/20 2
P 01/06/20 5
T 01/12/19 4
T 01/01/20 1
T 01/02/20 null
T 01/03/20 null
T 01/04/20 null
T 01/05/20 null
T 01/06/20 null
你能帮帮我吗?
一个选项使用递归查询来生成日期。然后,您可以 cross join
它与 table 中可用的不同 name
,最后将 table 与 left join
:
with cte (dt, max_dt) as (
select min(dt), max(dt) from mytable
union all
select dt + interval '1' month, max_dt from cte where dt < max_dt
)
select c.dt, n.name, t.cnt
from cte c
cross join (select distinct name from mytable) n
left join mytable t on t.name = n.name and t.dt = c.dt
order by n.name, c.dt
请注意,date
和 count
在 Oracle 中不是有效标识符 - 我在查询中将它们重命名为 dt
和 cnt
。
DT | NAME | CNT
:-------- | :--- | ---:
01-DEC-19 | P | null
01-JAN-20 | P | 4
01-FEB-20 | P | null
01-MAR-20 | P | 3
01-APR-20 | P | null
01-MAY-20 | P | 2
01-JUN-20 | P | 5
01-DEC-19 | T | 4
01-JAN-20 | T | 1
01-FEB-20 | T | null
01-MAR-20 | T | null
01-APR-20 | T | null
01-MAY-20 | T | null
01-JUN-20 | T | null
查找最小和最大月份,使用此值创建日历,将此日历与您的 table:
with
dates as (select min(date_) mnd, max(date_) mxd from tbl),
cal as (select add_months(mnd, level - 1) mth
from dates connect by level - 1 <= months_between(mxd, mnd))
select * from cal left join tbl partition by (name) on (date_ = mth)
您可以按如下方式使用行生成器技术:
WITH DATES(DT) AS
(SELECT ADD_MONTHS(TRUNC(SYSDATE,'MON'),LEVEL-1) FROM DUAL CONNECT BY LEVEL <= 7) -- use logic as per your requirement
SELECT NM.NAME, D.DT, T.COUNT
FROM DATES D
JOIN (SELECT DISTINCT NAME FROM YOUR_TABLE) NM ON 1=1 --CROSS JOIN FOR CREATING 7 RECORDS FOR EACH NAMES
LEFT JOIN YOUR_TABLE T ON D.DT = T.DATE AND NM.NAME = T.NAME
insert into table_name values ("P","01/12/19","");
insert into table_name values ("P","01/02/20","");
insert into table_name values ("P","01/04/20","");
insert into table_name values ("T","01/02/20","");
insert into table_name values ("T","01/03/20","");
insert into table_name values ("T","01/04/20","");
insert into table_name values ("T","01/05/20","");
insert into table_name values ("T","01/06/20","");
然后查询这个:
select * from table_name order by Name asc, Date asc;
我想寻求一点帮助。
我有以下数据
Name Date Count
P 01/01/20 4
P 01/03/20 3
P 01/05/20 2
P 01/06/20 5
T 01/12/19 4
T 01/01/20 1
我想在计数字段中添加空行,以获得以下结果
Name Date Count
P 01/12/19 null
P 01/01/20 4
P 01/02/20 null
P 01/03/20 3
P 01/04/20 null
P 01/05/20 2
P 01/06/20 5
T 01/12/19 4
T 01/01/20 1
T 01/02/20 null
T 01/03/20 null
T 01/04/20 null
T 01/05/20 null
T 01/06/20 null
你能帮帮我吗?
一个选项使用递归查询来生成日期。然后,您可以 cross join
它与 table 中可用的不同 name
,最后将 table 与 left join
:
with cte (dt, max_dt) as (
select min(dt), max(dt) from mytable
union all
select dt + interval '1' month, max_dt from cte where dt < max_dt
)
select c.dt, n.name, t.cnt
from cte c
cross join (select distinct name from mytable) n
left join mytable t on t.name = n.name and t.dt = c.dt
order by n.name, c.dt
请注意,date
和 count
在 Oracle 中不是有效标识符 - 我在查询中将它们重命名为 dt
和 cnt
。
DT | NAME | CNT :-------- | :--- | ---: 01-DEC-19 | P | null 01-JAN-20 | P | 4 01-FEB-20 | P | null 01-MAR-20 | P | 3 01-APR-20 | P | null 01-MAY-20 | P | 2 01-JUN-20 | P | 5 01-DEC-19 | T | 4 01-JAN-20 | T | 1 01-FEB-20 | T | null 01-MAR-20 | T | null 01-APR-20 | T | null 01-MAY-20 | T | null 01-JUN-20 | T | null
查找最小和最大月份,使用此值创建日历,将此日历与您的 table:
with
dates as (select min(date_) mnd, max(date_) mxd from tbl),
cal as (select add_months(mnd, level - 1) mth
from dates connect by level - 1 <= months_between(mxd, mnd))
select * from cal left join tbl partition by (name) on (date_ = mth)
您可以按如下方式使用行生成器技术:
WITH DATES(DT) AS
(SELECT ADD_MONTHS(TRUNC(SYSDATE,'MON'),LEVEL-1) FROM DUAL CONNECT BY LEVEL <= 7) -- use logic as per your requirement
SELECT NM.NAME, D.DT, T.COUNT
FROM DATES D
JOIN (SELECT DISTINCT NAME FROM YOUR_TABLE) NM ON 1=1 --CROSS JOIN FOR CREATING 7 RECORDS FOR EACH NAMES
LEFT JOIN YOUR_TABLE T ON D.DT = T.DATE AND NM.NAME = T.NAME
insert into table_name values ("P","01/12/19","");
insert into table_name values ("P","01/02/20","");
insert into table_name values ("P","01/04/20","");
insert into table_name values ("T","01/02/20","");
insert into table_name values ("T","01/03/20","");
insert into table_name values ("T","01/04/20","");
insert into table_name values ("T","01/05/20","");
insert into table_name values ("T","01/06/20","");
然后查询这个:
select * from table_name order by Name asc, Date asc;