SQL 计算十年内存在的记录
SQL to Count Records that Existed by Decade
我有一个 Oracle a table,它有 3 列。 FILE_NUM、START_DATE、END_DATE。 FILE_NUM 是唯一标识符,因此每一行都是唯一的。
FILE_NUM
START_DATE
END_DATE
1111
Apr. 04, 1977
Jun. 30, 1984
1112
Jan. 03, 1987
Sep. 05, 2010
1113
May. 14, 1962
Jan. 30, 1998
1114
Oct. 09, 2001
Aug. 22, 2025
1113
May. 14, 1962
Jan. 30, 1998
1114
Nov. 18, 2003
Aug. 22, 2028
etc
我想查询每十年存在的文件数。类似于:
Decade
Count
1960-1969
10
1970-1979
25
1980-1989
42
逻辑是,如果该文件在任何十年的任何时间点存在,则将其计入这十年中的每一个。所以对于 file_num 1112,应该算在 1980 年代、1990 年代、2000 年代和 2010 年代。
我什至不知道这是否可能。我已经在我的查询中修改了几次,但我不确定我是否知道足够的函数或技术来获得这种结果。
感谢您的帮助。
编辑:
我应该说明如何进行计数。我需要以 3 种方式处理日期范围,以便捕获每个十年内存在哪些 file_num。
- 如果它在十进制范围内开始,算上它。
- 如果它在十进制范围内结束,算它。
- 如果它在十进制范围之前开始并在十进制范围之后结束,则计算它。
我制作了以下 SQL。我仍在试图弄清楚它是否在做我想让它做的事情。如果有人有建议
with decades as
(
select
concat(concat(floor(extract(year from t.start_date)/10)*10, '-'), floor(extract(year from t.start_date)/10)*10 + 9) DECADE
from
table t
group by
concat(concat(floor(extract(year from t.start_date)/10)*10, '-'), floor(extract(year from t.start_date)/10)*10 + 9)
)
select
count(a.file_num),
decades.decade
from
table a,
decades
where
extract(year from a.start_date) between extract(year from to_date(SUBSTR(decades.decade,0,4), 'YYYY')) and extract(year from to_date(SUBSTR(decades.decade,6,9), 'YYYY'))
or
extract(year from a.end_date) between extract(year from to_date(SUBSTR(decades.decade,0,4), 'YYYY')) and extract(year from to_date(SUBSTR(decades.decade,6,9), 'YYYY'))
or
(extract(year from a.start_date) < extract(year from to_date(SUBSTR(decades.decade,0,4), 'YYYY'))
and
extract(year from a.end_date) > extract(year from to_date(SUBSTR(decades.decade,6,9), 'YYYY'))
)
group by
decades.decade
order by
decades.decade
最好的选择可以是十年维度 table:
并加入主要 table:
select d.decade,
count(file_num) as count
from table m
join decade d
on m.start_date >= d.decade_start_date
join decade d2
on m.end_date <= d2.decade_end_date
where 1 = 1
and d.decade = d2.decade
group by 1
您应该能够通过将日期的年份除以 10 转换为一个整数,然后将其乘以 10 来组合一些东西。示例...
2019 / 10 = 201.9 cast as integer = 201 * 10 = 2010
然后,在上面加上 9 年作为结束年份
2019 + 10 = 2029 / 10 = 202.9 cast as integer = 202 * 10 = 2020 + 9 = 2029
所以,您应该关心的是开始日期...类似
select
concat( cast( EXTRACT(YEAR FROM m.start_date ) / 10 as int ) * 10,
concat( '-',
cast( EXTRACT(YEAR FROM m.start_date ) / 10 as int ) * 10 + 9)),
count(*) as NumRecs
from
table m
group by 1
您也可以利用 connect by 子句来做到这一点。
我假设您的真实数据中没有任何重复行(这些列 FILE_NUM、START_DATE、END_DATE 应该是唯一的)。
SELECT dec_start, dec_end, COUNT(*) nb
FROM (
SELECT t.*, level
, 10 * trunc( extract ( year from (START_DATE) ) / 10 ) + 10 * LEVEL - 10 dec_start
, 10 * trunc( extract ( year from (START_DATE) ) / 10 ) + 10 * LEVEL - 1 dec_end
FROM YourTable T
CONNECT BY
10 * TRUNC( EXTRACT ( YEAR FROM (START_DATE) ) / 10 ) + 10 * LEVEL - 10
< 10 * CEIL( EXTRACT ( YEAR FROM (END_DATE) ) / 10 )
AND PRIOR FILE_NUM = FILE_NUM
AND PRIOR START_DATE = START_DATE
AND PRIOR END_DATE = END_DATE
AND PRIOR SYS_GUID() IS NOT NULL
)
group by dec_start, dec_end
order by dec_start, dec_end
;
我有一个 Oracle a table,它有 3 列。 FILE_NUM、START_DATE、END_DATE。 FILE_NUM 是唯一标识符,因此每一行都是唯一的。
FILE_NUM | START_DATE | END_DATE |
---|---|---|
1111 | Apr. 04, 1977 | Jun. 30, 1984 |
1112 | Jan. 03, 1987 | Sep. 05, 2010 |
1113 | May. 14, 1962 | Jan. 30, 1998 |
1114 | Oct. 09, 2001 | Aug. 22, 2025 |
1113 | May. 14, 1962 | Jan. 30, 1998 |
1114 | Nov. 18, 2003 | Aug. 22, 2028 |
etc |
我想查询每十年存在的文件数。类似于:
Decade | Count |
---|---|
1960-1969 | 10 |
1970-1979 | 25 |
1980-1989 | 42 |
逻辑是,如果该文件在任何十年的任何时间点存在,则将其计入这十年中的每一个。所以对于 file_num 1112,应该算在 1980 年代、1990 年代、2000 年代和 2010 年代。
我什至不知道这是否可能。我已经在我的查询中修改了几次,但我不确定我是否知道足够的函数或技术来获得这种结果。
感谢您的帮助。
编辑:
我应该说明如何进行计数。我需要以 3 种方式处理日期范围,以便捕获每个十年内存在哪些 file_num。
- 如果它在十进制范围内开始,算上它。
- 如果它在十进制范围内结束,算它。
- 如果它在十进制范围之前开始并在十进制范围之后结束,则计算它。
我制作了以下 SQL。我仍在试图弄清楚它是否在做我想让它做的事情。如果有人有建议
with decades as
(
select
concat(concat(floor(extract(year from t.start_date)/10)*10, '-'), floor(extract(year from t.start_date)/10)*10 + 9) DECADE
from
table t
group by
concat(concat(floor(extract(year from t.start_date)/10)*10, '-'), floor(extract(year from t.start_date)/10)*10 + 9)
)
select
count(a.file_num),
decades.decade
from
table a,
decades
where
extract(year from a.start_date) between extract(year from to_date(SUBSTR(decades.decade,0,4), 'YYYY')) and extract(year from to_date(SUBSTR(decades.decade,6,9), 'YYYY'))
or
extract(year from a.end_date) between extract(year from to_date(SUBSTR(decades.decade,0,4), 'YYYY')) and extract(year from to_date(SUBSTR(decades.decade,6,9), 'YYYY'))
or
(extract(year from a.start_date) < extract(year from to_date(SUBSTR(decades.decade,0,4), 'YYYY'))
and
extract(year from a.end_date) > extract(year from to_date(SUBSTR(decades.decade,6,9), 'YYYY'))
)
group by
decades.decade
order by
decades.decade
最好的选择可以是十年维度 table:
并加入主要 table:
select d.decade,
count(file_num) as count
from table m
join decade d
on m.start_date >= d.decade_start_date
join decade d2
on m.end_date <= d2.decade_end_date
where 1 = 1
and d.decade = d2.decade
group by 1
您应该能够通过将日期的年份除以 10 转换为一个整数,然后将其乘以 10 来组合一些东西。示例...
2019 / 10 = 201.9 cast as integer = 201 * 10 = 2010
然后,在上面加上 9 年作为结束年份
2019 + 10 = 2029 / 10 = 202.9 cast as integer = 202 * 10 = 2020 + 9 = 2029
所以,您应该关心的是开始日期...类似
select
concat( cast( EXTRACT(YEAR FROM m.start_date ) / 10 as int ) * 10,
concat( '-',
cast( EXTRACT(YEAR FROM m.start_date ) / 10 as int ) * 10 + 9)),
count(*) as NumRecs
from
table m
group by 1
您也可以利用 connect by 子句来做到这一点。 我假设您的真实数据中没有任何重复行(这些列 FILE_NUM、START_DATE、END_DATE 应该是唯一的)。
SELECT dec_start, dec_end, COUNT(*) nb
FROM (
SELECT t.*, level
, 10 * trunc( extract ( year from (START_DATE) ) / 10 ) + 10 * LEVEL - 10 dec_start
, 10 * trunc( extract ( year from (START_DATE) ) / 10 ) + 10 * LEVEL - 1 dec_end
FROM YourTable T
CONNECT BY
10 * TRUNC( EXTRACT ( YEAR FROM (START_DATE) ) / 10 ) + 10 * LEVEL - 10
< 10 * CEIL( EXTRACT ( YEAR FROM (END_DATE) ) / 10 )
AND PRIOR FILE_NUM = FILE_NUM
AND PRIOR START_DATE = START_DATE
AND PRIOR END_DATE = END_DATE
AND PRIOR SYS_GUID() IS NOT NULL
)
group by dec_start, dec_end
order by dec_start, dec_end
;