<legend id='Usmow'><style id='Usmow'><dir id='Usmow'><q id='Usmow'></q></dir></style></legend>

  • <small id='Usmow'></small><noframes id='Usmow'>

  • <i id='Usmow'><tr id='Usmow'><dt id='Usmow'><q id='Usmow'><span id='Usmow'><b id='Usmow'><form id='Usmow'><ins id='Usmow'></ins><ul id='Usmow'></ul><sub id='Usmow'></sub></form><legend id='Usmow'></legend><bdo id='Usmow'><pre id='Usmow'><center id='Usmow'></center></pre></bdo></b><th id='Usmow'></th></span></q></dt></tr></i><div id='Usmow'><tfoot id='Usmow'></tfoot><dl id='Usmow'><fieldset id='Usmow'></fieldset></dl></div>
      <tfoot id='Usmow'></tfoot>
        <bdo id='Usmow'></bdo><ul id='Usmow'></ul>

      1. ORACLE SQL 日期范围交集

        时间:2023-11-02
            <i id='04WGv'><tr id='04WGv'><dt id='04WGv'><q id='04WGv'><span id='04WGv'><b id='04WGv'><form id='04WGv'><ins id='04WGv'></ins><ul id='04WGv'></ul><sub id='04WGv'></sub></form><legend id='04WGv'></legend><bdo id='04WGv'><pre id='04WGv'><center id='04WGv'></center></pre></bdo></b><th id='04WGv'></th></span></q></dt></tr></i><div id='04WGv'><tfoot id='04WGv'></tfoot><dl id='04WGv'><fieldset id='04WGv'></fieldset></dl></div>

          • <small id='04WGv'></small><noframes id='04WGv'>

              <tbody id='04WGv'></tbody>
          • <tfoot id='04WGv'></tfoot><legend id='04WGv'><style id='04WGv'><dir id='04WGv'><q id='04WGv'></q></dir></style></legend>

                  <bdo id='04WGv'></bdo><ul id='04WGv'></ul>
                  本文介绍了ORACLE SQL 日期范围交集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有一个表 T1,它包含一个 NAME 值(不是唯一的)和一个日期范围(D1 和 D2 是日期)当 NAME 相同时,我们对日期范围进行联合(例如 B).

                  I have a table T1, it contains a NAME value (not unique), and a date range (D1 and D2 which are dates) When NAME are the same, we make a union of the date ranges (e.g. B).

                  但作为结果 (X),我们需要对所有日期范围进行交集

                  But as a result (X), we need to make intersection of all the date ranges

                  表T1

                  NAME | D1       | D2
                  A    | 20100101 | 20101211
                  B    | 20100120 | 20100415
                  B    | 20100510 | 20101230
                  C    | 20100313 | 20100610
                  

                  结果:

                  X    | 20100313 | 20100415
                  X    | 20100510 | 20100610
                  

                  在视觉上,这将给出以下内容:

                  Visually, this will give the following :

                  NAME        : date range
                  A           : [-----------------------]-----
                  B           : --[----]----------------------
                  B           : ----------[---------------]---
                  C           : -----[--------]---------------
                  

                  结果:

                  X           : -----[-]----------------------
                  X           : ----------[---]---------------
                  

                  知道如何使用 SQL/PL SQL 获得它吗?

                  Any idea how to get that using SQL / PL SQL ?

                  推荐答案

                  这里有一个快速的解决方案(可能不是最有效的):

                  here is a quick solution (may not be the most efficient):

                  SQL> CREATE TABLE myData AS
                    2  SELECT 'A' name, date'2010-01-01' d1, date'2010-12-11' d2 FROM DUAL
                    3  UNION ALL SELECT 'B', date'2010-01-20', date'2010-04-15' FROM DUAL
                    4  UNION ALL SELECT 'B', date'2010-05-10', date'2010-12-30' FROM DUAL
                    5  UNION ALL SELECT 'C', date'2010-03-13', date'2010-06-10' FROM DUAL;
                  
                  Table created
                  
                  SQL> WITH segments AS (
                    2  SELECT dat seg_low, lead(dat) over(ORDER BY dat) seg_high
                    3    FROM (SELECT d1 dat FROM myData
                    4           UNION
                    5           SELECT d2 dat FROM myData)
                    6  )
                    7  SELECT s.seg_low, s.seg_high
                    8    FROM segments s
                    9    JOIN myData m ON s.seg_high > m.d1
                   10                 AND s.seg_low < m.d2
                   11   GROUP BY s.seg_low, s.seg_high
                   12  HAVING COUNT(DISTINCT NAME) = 3;
                  
                  SEG_LOW     SEG_HIGH
                  ----------- -----------
                  13/03/2010  15/04/2010
                  10/05/2010  10/06/2010
                  

                  我构建了所有可能的连续日期范围,并将此日历"与示例数据结合起来.这将列出具有 3 个值的所有范围.如果添加行,您可能需要合并结果:

                  I build all the possible successive date ranges and join this "calendar" with the sample data. This will list all ranges that have 3 values. You may need to merge the result if you add rows:

                  SQL> insert into mydata values ('B',date'2010-04-15',date'2010-04-16');
                  
                  1 row inserted
                  
                  SQL> WITH segments AS (
                    2  SELECT dat seg_low, lead(dat) over(ORDER BY dat) seg_high
                    3    FROM (SELECT d1 dat FROM myData
                    4           UNION
                    5           SELECT d2 dat FROM myData)
                    6  )
                    7  SELECT MIN(seg_low), MAX(seg_high)
                    8    FROM (SELECT seg_low, seg_high, SUM(gap) over(ORDER BY seg_low) grp
                    9             FROM (SELECT s.seg_low, s.seg_high,
                   10                           CASE
                   11                              WHEN s.seg_low
                   12                                   = lag(s.seg_high) over(ORDER BY s.seg_low)
                   13                              THEN 0
                   14                              ELSE 1
                   15                           END gap
                   16                      FROM segments s
                   17                      JOIN myData m ON s.seg_high > m.d1
                   18                                   AND s.seg_low < m.d2
                   19                     GROUP BY s.seg_low, s.seg_high
                   20                    HAVING COUNT(DISTINCT NAME) = 3))
                   21   GROUP BY grp;
                  
                  MIN(SEG_LOW) MAX(SEG_HIGH)
                  ------------ -------------
                  13/03/2010   16/04/2010
                  10/05/2010   10/06/2010
                  

                  这篇关于ORACLE SQL 日期范围交集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:我什么时候应该嵌套 PL/SQL BEGIN...END 块? 下一篇:如何在 PL/SQL 中迭代日期范围

                  相关文章

                • <small id='WdWnG'></small><noframes id='WdWnG'>

                  <legend id='WdWnG'><style id='WdWnG'><dir id='WdWnG'><q id='WdWnG'></q></dir></style></legend>
                  <i id='WdWnG'><tr id='WdWnG'><dt id='WdWnG'><q id='WdWnG'><span id='WdWnG'><b id='WdWnG'><form id='WdWnG'><ins id='WdWnG'></ins><ul id='WdWnG'></ul><sub id='WdWnG'></sub></form><legend id='WdWnG'></legend><bdo id='WdWnG'><pre id='WdWnG'><center id='WdWnG'></center></pre></bdo></b><th id='WdWnG'></th></span></q></dt></tr></i><div id='WdWnG'><tfoot id='WdWnG'></tfoot><dl id='WdWnG'><fieldset id='WdWnG'></fieldset></dl></div>
                  1. <tfoot id='WdWnG'></tfoot>

                        <bdo id='WdWnG'></bdo><ul id='WdWnG'></ul>