Sql 查询时间范围内基于生效日期的结果
以下是我尝试为其创建查询的表结构格式:Sql 查询时间范围内基于生效日期的结果,sql,database,oracle,sqlite,date,Sql,Database,Oracle,Sqlite,Date,以下是我尝试为其创建查询的表结构格式: ProductName | Effective_Date |version_number --------------------------------------------- Product1 01-Jan-02 1 Product1 05-Oct-03 2 Product1 03-Mar-04 3 Product1 12-Oct-04
ProductName | Effective_Date |version_number
---------------------------------------------
Product1 01-Jan-02 1
Product1 05-Oct-03 2
Product1 03-Mar-04 3
Product1 12-Oct-04 4
Product1 04-May-05 5
Product1 15-Sep-06 6
Product2 01-Jun-02 1
Product2 03-Sep-08 2
Product3 04-Jun-10 1
Product3 05-Sep-11 2
Product4 16-Jun-03 1
Product4 17-Oct-03 2
Product5 07-Feb-05 1
Product6 01-Jun-02 1
Product6 03-Dec-05 2
Product7 03-Feb-04 1
Product7 05-Nov-10 2
我需要找出在2004-2005年间有效的版本。版本的生效日期确定为:
对于产品1,版本1的有效期为2002年1月1日至2003年10月4日,版本2的有效期为2003年10月5日至2004年3月2日,依此类推
所以版本的有效性是从生效日期到下一个版本创建日期-1
这可能有不同的情况:
请帮助我实现此查询。假设您的表名为
i
:
SELECT
i.PRODUCTNAME
, I.VERSION_NUMBER
, I.EFFECTIVE_DATE START_DATE
, i2.effective_date end_date
from i
left join i i2 on i2.version_number = i.version_number +1 and i2.productname = i.productname
where NOT ((I.EFFECTIVE_DATE <= '01/01/2004' AND nvl(i2.effective_date,sysdate) <= '01/01/2004') OR (I.EFFECTIVE_DATE >= '12/31/2005' AND nvl(i2.effective_date,sysdate) >= '12/31/2005'))
选择
i、 产品名称
,I.版本号
,I.生效日期开始日期
,i2.生效日期结束日期
从我
在i2.version\u number=i.version\u number+1和i2.productname=i.productname上左键连接i2
其中不包括((I.生效日期='12/31/2005'))
我创建了开始
和结束
日期,只是使用了下一个版本的生效日期
来匹配产品(假设您不跳过版本,如果跳过,则需要分区/订购)
有两种情况需要避免。给定的产品/版本在2004年1月1日之前启动和停止,或在2005年12月31日之后启动和停止。要保留的任何其他开始/结束日期组合
对于没有结束日期的最新版本,我们使用sysdate
下面的查询将显示2004年1月1日至2005年12月31日期间“生效”的所有版本。它不显示在该时间间隔内没有任何有效版本的产品;如果您需要显示所有的产品,包括这些产品,您将需要一个到“products”表的左外部联接(假设它是一个单独的、较小的联接)
Oracle还是sqlite?我以为我理解需求,但也许我不理解。您是否需要2004年和2005年期间任何时候处于活动状态的所有版本?或者仅仅是2005年底启用的版本?所有版本均在2014年1月1日至2015年12月31日期间生效。我感谢您的努力。10月17日生效的产品4缺少一行-03@ShekharSharma有道理,这是最新版本,答案更新
with
test_data ( ProductName, Effective_Date, version_number ) as (
select 'Product1', to_date('01-Jan-02', 'dd-Mon-rr'), 1 from dual union all
select 'Product1', to_date('05-Oct-03', 'dd-Mon-rr'), 2 from dual union all
select 'Product1', to_date('03-Mar-04', 'dd-Mon-rr'), 3 from dual union all
select 'Product1', to_date('12-Oct-04', 'dd-Mon-rr'), 4 from dual union all
select 'Product1', to_date('04-May-05', 'dd-Mon-rr'), 5 from dual union all
select 'Product1', to_date('15-Sep-06', 'dd-Mon-rr'), 6 from dual union all
select 'Product2', to_date('01-Jun-02', 'dd-Mon-rr'), 1 from dual union all
select 'Product2', to_date('03-Sep-08', 'dd-Mon-rr'), 2 from dual union all
select 'Product3', to_date('04-Jun-10', 'dd-Mon-rr'), 1 from dual union all
select 'Product3', to_date('05-Sep-11', 'dd-Mon-rr'), 2 from dual union all
select 'Product4', to_date('16-Jun-03', 'dd-Mon-rr'), 1 from dual union all
select 'Product4', to_date('17-Oct-03', 'dd-Mon-rr'), 2 from dual union all
select 'Product5', to_date('07-Feb-05', 'dd-Mon-rr'), 1 from dual union all
select 'Product6', to_date('01-Jun-02', 'dd-Mon-rr'), 1 from dual union all
select 'Product6', to_date('03-Dec-05', 'dd-Mon-rr'), 2 from dual union all
select 'Product7', to_date('03-Feb-04', 'dd-Mon-rr'), 1 from dual union all
select 'Product7', to_date('05-Nov-10', 'dd-Mon-rr'), 2 from dual
)
-- End of test data (NOT part of the SQL query). Query begins BELOW THIS LINE.
select productname, effective_date, to_date - 1 as to_date, version_number
from ( select productname, effective_date,
lead(effective_date, 1, date '2099-01-01')
over (partition by productname order by effective_date) as to_date,
version_number
from test_data
)
where effective_date < date '2006-01-01'
and to_date >= date '2004-01-01'
;
PRODUCTNAME EFFECTIVE_DATE TO_DATE VERSION_NUMBER
------------ --------------- --------------- --------------
Product1 05-Oct-03 02-Mar-04 2
Product1 03-Mar-04 11-Oct-04 3
Product1 12-Oct-04 03-May-05 4
Product1 04-May-05 14-Sep-06 5
Product2 01-Jun-02 02-Sep-08 1
Product4 17-Oct-03 31-Dec-98 2
Product5 07-Feb-05 31-Dec-98 1
Product6 01-Jun-02 02-Dec-05 1
Product6 03-Dec-05 31-Dec-98 2
Product7 03-Feb-04 04-Nov-10 1
10 rows selected.