1

最近在oracle sql中遇到一个问题。花了很多时间试图弄清楚,但似乎很难实现。因此,如果有人可以提供帮助,那就太好了!

问题很简单,我想连接不同行中的重复项,以便找到“真正的开始”和“真正的结束”,例如,

ID  Start date  End date    Line
1   8/25/2013   8/27/2013   1
1   8/27/2013   8/30/2013   2
2   8/20/2013   8/27/2013   1
2   9/1/2013    9/4/2013    2
2   9/4/2013    9/5/2013    3
2   9/5/2013    9/7/2013    4

所以你可以看到,对于同一个ID,它有多个“开始”和“结束”,但其中一些是一致的(结束日期与其下一个开始日期相同)。我想做的是对数据进行排序并删除一些重复项。例如,结果应该是,

ID  Start date  End date
1   8/25/2013   8/30/2013
2   8/20/2013   8/27/2013
2   9/1/2013    9/7/2013

如果有人可以提供一些提示,我真的很感激。我尝试了“引导”功能,但似乎解决这个问题还需要更多。另外,我尝试将此查询复制到 Access,您知道它没有太多花哨的功能,所以第二个问题是这是否可以在 Access 中实现。谢谢...

4

2 回答 2

0

这就是我想出的,我很想用更多的数据来尝试一下,但本质上,我所做的只是确保 (id, start_date) 的组合不作为 (id, end_date) 存在.

我想当一个特定的 id 具有相同的开始日期和结束日期时,错误可能会出现——你应该测试一下。

希望这能让你达到 80%(但是,它可以工作并返回你想要的输出):

SELECT id, start_date
  FROM table1 mst
 WHERE (id, start_date) NOT IN (SELECT id, end_date FROM table1)

验证(sqlfiddle):http ://sqlfiddle.com/#!4/6116f/20/0

于 2013-10-21T20:44:33.097 回答
0

有趣的问题。请问你在哪里找到的?下面是我的提议。我还没有彻底测试它,但我会的,因为我也有兴趣找到一个合适的解决方案来解决这个问题。困难的部分是找到该START WITH子句的所有记录,但对于我用于测试的数据,它返回了正确的结果集。我希望有人会发布一个更简单的解决方案,也许使用分析函数(我自己没有成功)。

好的,代码如下:

CREATE TABLE my_data (
  id NUMBER,
  start_date DATE,
  end_date DATE,
  line NUMBER
);

INSERT INTO my_data VALUES (1, DATE '2013-08-25', DATE '2013-08-27', 1);
INSERT INTO my_data VALUES (1, DATE '2013-08-27', DATE '2013-08-30', 2);
INSERT INTO my_data VALUES (2, DATE '2013-08-20', DATE '2013-08-27', 1);
INSERT INTO my_data VALUES (2, DATE '2013-09-01', DATE '2013-09-04', 2);
INSERT INTO my_data VALUES (2, DATE '2013-09-04', DATE '2013-09-05', 3);
INSERT INTO my_data VALUES (2, DATE '2013-09-05', DATE '2013-09-07', 4);

COMMIT;

SELECT
    id,
    root_start_date AS start_date,
    MAX(end_date) AS end_date
  FROM (
    SELECT
        id,
        start_date,
        end_date,
        CONNECT_BY_ROOT start_date AS root_start_date
      FROM my_data
    START WITH (id, start_date) IN (
                            SELECT id, start_date
                              FROM my_data md
                            WHERE
                              NOT EXISTS (
                                SELECT 1
                                  FROM my_data
                                WHERE id = md.id
                                  AND md.start_date BETWEEN start_date AND end_date
                                  AND end_date < md.end_date
                                )
    )
    CONNECT BY start_date >= PRIOR start_date
            AND start_date <= PRIOR end_date
            AND end_date > PRIOR end_date
            AND id = PRIOR id
  )
GROUP BY id, root_start_date
ORDER BY id, start_date
;

结果:

        ID START_DATE END_DATE
---------- ---------- --------
         1 13/08/25 13/08/30
         2 20 年 8 月 13 日 27 年 8 月 13 日
         2 01 年 9 月 13 日 07 年 9 月 13 日
于 2013-10-22T00:13:55.710 回答