查询时间范围的基于生效日期的结果

时间:2017-01-20 20:16:54

标签: 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          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。

可能存在不同的情况:

  1. 2004-2005没有生效日期的版本,因此在这种情况下,日期< 2004年将有效
  2. 版本是在2004-2005,如果生效日期是2004年3月25日那么版本应该有效,直到2004年3月24日。
  3. 请帮我实现此问题的查询。

2 个答案:

答案 0 :(得分: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'))

我创建startend日期只是使用下一个版本的effective_date来匹配产品(假设您不跳过版本,如果您确实需要分区/订购)。

您希望避免两种情况。给定的产品/版本在2004年1月1日之前开始或停止,或者在2005年12月31日之后开始和停止。您想要保留的任何其他开始/结束日期组合。

我们将sysdate用于没有end date

的最新版本

here is a functional example

答案 1 :(得分:0)

下面的查询将显示&#34;生效的所有版本&#34;在2004年1月1日到2005年12月31日之间。它没有显示在该时间间隔内没有任何版本的产品;如果您需要展示所有产品,包括这些产品,您需要在您的产品中使用左外连接&#34;表(假设它是一个单独的,较小的一个)。

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.
相关问题