如何根据特定日期条件创建数据集?

时间:2018-10-22 14:47:02

标签: sql oracle

我有以下方式的数据集

year mon date      org
---- --- --------- ---
2018 mar 21-Mar-18 bb2
2018 mar 19-Mar-18 bbd
2018 feb 17-Feb-18 bbc
2018 feb 15-Feb-18 bba
2018 jan 15-Jan-18 abb
2018 jan 13-Jan-18 abc

我正在尝试通过以下方式重复获取数据:

year mon date      org
---- --- --------- ---
2018 mar 21-Mar-18 bb2
2018 mar 19-Mar-18 bbd
2018 mar 17-Feb-18 bbc
2018 mar 15-Feb-18 bba
2018 mar 15-Jan-18 abb
2018 mar 13-Jan-18 abc
2018 feb 17-Feb-18 bbc
2018 feb 15-Feb-18 bba
2018 feb 15-Jan-18 abb
2018 feb 13-Jan-18 abc
2018 jan 15-Jan-18 abb
2018 jan 13-Jan-18 abc

编辑: 抱歉,信息模糊。 这是一个独特的要求,它指出: “如果用户查询一个月,则输出应返回所选月份及其前几个月的所有行。”

因此,如果您查看我现有的数据集(这只是虚拟数据),如果我筛选了mar,则应该得到6行,feb为4行,jan为2行,依此类推。因此,整个数据将由一个表中的12行组成。

我正在使用oracle 11.2.0.3版

高度赞赏任何想法或投入。

编辑2: 对不起,我走了这么久。这项要求被取消了,所以我们没有走这条路。 但是,如果有人想走这条路,解决方案是

自行加入“ org”上的表,并且Tab_A.column X是> = Tab_B.column X

假设X是一个新列(基于year和mon,例如:201803)

2 个答案:

答案 0 :(得分:0)

要获取表中每个月/年的最新日期,可以将maxgroup by一起使用,如下所示(未提供表名,我们将其命名为myTable ):

SELECT year, mon, max(date) FROM myTable GROUP BY year, mon

然后可以通过联接来获取重复的数据:

SELECT m2.year, m2.mon, m.date, m.org
FROM myTable AS m
    INNER JOIN (SELECT year, mon, max(date) AS maxDate FROM myTable GROUP BY year, mon) AS m2
        ON m.date <= m2.maxDate
ORDER BY m2.maxDate DESC, m.date DESC

答案 1 :(得分:0)

如果用户希望在一个月和一年中通过,则需要行,这应该可以解决问题:

WITH your_table AS (SELECT 2018 YEAR, 'mar' mon, to_date('21/03/2018', 'dd/mm/yyyy') dt, 'bb2' org FROM dual UNION ALL
                    SELECT 2018 YEAR, 'mar' mon, to_date('19/03/2018', 'dd/mm/yyyy') dt, 'bbd' org FROM dual UNION ALL
                    SELECT 2018 YEAR, 'feb' mon, to_date('17/02/2018', 'dd/mm/yyyy') dt, 'bbc' org FROM dual UNION ALL
                    SELECT 2018 YEAR, 'feb' mon, to_date('15/02/2018', 'dd/mm/yyyy') dt, 'bba' org FROM dual UNION ALL
                    SELECT 2018 YEAR, 'jan' mon, to_date('15/01/2018', 'dd/mm/yyyy') dt, 'abb' org FROM dual UNION ALL
                    SELECT 2018 YEAR, 'jan' mon, to_date('13/01/2018', 'dd/mm/yyyy') dt, 'abc' org FROM dual)
-- end of sample data setup
SELECT *
FROM   your_table
WHERE  to_date(mon||'/'||YEAR, 'mon/yyyy', 'nls_date_language = english') <= to_date(:dt, 'mon/yyyy', 'nls_date_language = english');

:dt = 2018年4月

      YEAR MON DT          ORG
---------- --- ----------- ---
      2018 mar 21/03/2018  bb2
      2018 mar 19/03/2018  bbd
      2018 feb 17/02/2018  bbc
      2018 feb 15/02/2018  bba
      2018 jan 15/01/2018  abb
      2018 jan 13/01/2018  abc

:dt = 2018年3月

      YEAR MON DT          ORG
---------- --- ----------- ---
      2018 mar 21/03/2018  bb2
      2018 mar 19/03/2018  bbd
      2018 feb 17/02/2018  bbc
      2018 feb 15/02/2018  bba
      2018 jan 15/01/2018  abb
      2018 jan 13/01/2018  abc

:dt = 2018年2月

      YEAR MON DT          ORG
---------- --- ----------- ---
      2018 feb 17/02/2018  bbc
      2018 feb 15/02/2018  bba
      2018 jan 15/01/2018  abb
      2018 jan 13/01/2018  abc

:dt =一月/ 2018

      YEAR MON DT          ORG
---------- --- ----------- ---
      2018 jan 15/01/2018  abb
      2018 jan 13/01/2018  abc

:dt = 2017年12月

no rows selected

您需要相应地修改输入;在我的查询中,我假设要查询的月份将为mon/yyyy格式;

此外,由于我们使用的是mon,因此我添加了第三个可选参数,以确保我们使用正确的日期语言进行查询。如果客户端的语言是法语,但是数据的语言是英语,则该查询将无法工作!

最后,这似乎是一个糟糕的设计。您可以轻松地将此表更改为仅具有dt列,并向该表添加虚拟列以创建月和年列(尽管我不会将它们分开;我只需要trunc(dt, 'mm')并保留它作为额外的日期列。IMO更灵活),并相应地为虚拟列建立索引。