这是sqlite3,不包括我在这里读到的其他SQL实现的其他解决方案。
我有一个表 "DR",其中有,在其他数据中,"月"(1-12,不含零填充)和 "年"(yyyy)列都是文本列。
我想检索所有月年在两个特定配对之间的行,例如从2017年月6日到2020年月4日,这4个值也是以文本形式进来的(来自python),月份没有填充。我想确保也能处理不到一整年的情况,比如2017年月2日到2017年月10日。
我想出了如何通过蛮力与一个荒谬的数量的OR,从来没有接触到一个实际的日期相关的函数,但我想知道是否有一个更优雅的方式来做到这一点,利用sql实际上理解一个日期是大于或小于另一个日期,滚动月数跨年度边界。
谢谢你能提供任何帮助
如果你对你的问题理解正确的话--当你的表只包含月和年的数字时,你想应用一个日期范围过滤器?
你可以创建一个辅助的 "日期 "表加入到你的CR表。
create table digits (value integer);
-- create auxiliary digits table (for generating dates)
insert into digits values (1),(2),(3),(4),(5),(6),(7),(8),(9);
create table numbers (value integer);
-- create auxiliary numbers table (for generating dates)
insert into numbers (value)
select d1.value + d2.value * 10 + d3.value *100 as value
from digits as d1
cross join digits as d2
cross join digits as d3;
-- create auxliary dates table
create table dates (month_begin_date, month_number, year_number);
insert into dates (
month_begin_date
,month_number
,year_number)
select date('now', '-'|| value || ' day')
, cast(strftime('%m',date('now', '-'|| value || ' day')) as integer) as month_number
, cast(strftime('%Y',date('now', '-'|| value || ' day')) as Integer) as year_number
from numbers
where cast(strftime('%d',date('now', '-'|| value || ' day')) as integer) = 1;
create table CR (month_number integer, year_number integer, some_column varchar(100));
insert into CR values
(1, 2020, 'a'),
(2, 2020, 'b'),
(3, 2020, 'c'),
(4, 2020, 'd');
-- join 'CR' table to auxiliary table here for final filtering
select dates.month_begin_date, dates.month_number, dates.year_number, CR.some_column
from dates
inner join CR
on CR.month_number = dates.month_number
and CR.year_number = dates.year_number
where dates.month_begin_date > '1/1/2020' and dates.month_begin_date < '3/1/2020';
直接从 SQLite文档 - 比较作为单独字段存储的日期
通常在数据库表中存储日期的方法是作为一个单一的字段,如unix时间戳,julian日数,或者ISO-8601日期字符串。但有些应用程序将日期存储为年、月、日三个独立的字段。
CREATE TABLE info( year INT, -- 4 digit year month INT, -- 1 through 12 day INT, -- 1 through 31 other_stuff BLOB -- blah blah blah );
当日期以这种方式存储时,行值比较提供了一种方便的方式来比较日期。
SELECT * FROM info WHERE (year,month,day) BETWEEN (2015,9,12) AND (2016,9,12);