Tab A 中有以下column  ESD,LSD分别为日期值
        ID      ESD              LSD  
eg :  1        2007-06-01     2007-06-08
        2        2007-05-27     2007-06-04
        3         ''                          ''
        4        2007-06-25      2007-06-12
        5        ''                           ''分析: 
        ESD                              LSD
  |___________________________________|     ( A )
    2007/06/01                         2006/06/08 
           ------- 4 days---
ESD            LSD       
  |_________________________|   ( B )
2007/05/27                2007/06/04
                                -------4 days----
                                ESD                        LSD
                                |__________________________|  ( C )
                              2007/06/05                 2007/06/12 如图所示
其中如果以A为参照对象  
   B 为A的左区间
   C 为A的右区间
   B,C 同时都 满足: 与A有一个交叉的区间,且区间为 4days现在的问题就是
  如何通过 sql 神奇语句 找出所有 有相同区间的数据
  我头有点大了  , 谁能帮我 ???!!
在线侯教
   

解决方案 »

  1.   

    更正一下 A.LSD 为2007/06/08
      

  2.   

    CREATE TABLE TabA(ID INT IDENTITY(1,1),ESD SMALLDATETIME,LSD SMALLDATETIME)
    INSERT INTO TabA 
    SELECT '2007-06-01','2007-06-08' UNION ALL
    SELECT '2007-05-27','2007-06-04' UNION ALL
    SELECT '2007-06-01','2007-06-04' UNION ALL
    SELECT '2007-06-05','2007-06-12' UNION ALL
    SELECT '2007-06-05','2007-06-08' 
    --DROP TABLE TabASELECT '左区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,4,B.LSD) = A.LSD-- OR DATEADD(DAY ,-4,B.ESD) = A.ESD
    WHERE A.ID = 1
    UNION ALL
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,-4,B.ESD) = A.ESD
    WHERE A.ID = 1
      

  3.   

    SELECT '左区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,4,B.LSD) = A.LSD
    WHERE A.ID = 1
    UNION ALL
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,-4,B.ESD) = A.ESD
    WHERE A.ID = 1
      

  4.   

    To :simonhehe(流氓会武术,谁也挡不住)
    您的测试结果是对的,但问题好象没有哪么简单我们可以看出每条记录都有 ESD 和 LSD ,因此每条记录都有自已的左区间和右区间
    左区间[ESD-4days,LSD-4days]
    右区间[ESD+4days,LSD+4days]
    这个问题源于以下的需求 (散货: 不够装在一个柜子的货物)
    ESD 为出货日期
    LSD 为到目的地的日期 
    这两个时间构成这个封闭的时间区间[ESD,LSD](说明 : 一票货物的 ESD,或LSD 只可能在另一票货物的[ESD,LSD]的其中一个区间内
    ---即要么在左区间或要么在右区间,不可能周时在两个区间内,另外就是同时都不在两个区间内)如果A货物的 ESD和LSD 同时在B货物的左区间[ESD-4days,LSD-4days]内,我们就将A,B识为
    满足区间原则 
       或者
    如果A货物的 ESD和LSD 同时在B货物的右区间[ESD+4days,LSD+4days]内,我们也将A,B识为
    满足区间原则 我的问题就时要找出满足区间原则的数据集也许我这样描述会更清楚一些这个问题,我实在是没法独立解决,希望大家帮帮忙 
     
      

  5.   

    如果A货物的 ESD和LSD 同时在B货物的左区间[ESD-4days,LSD-4days]内,我们就将A,B识为
    满足区间原则 
       或者
    如果A货物的 ESD和LSD 同时在B货物的右区间[ESD+4days,LSD+4days]内,我们也将A,B识为
    满足区间原则 为了区分这两种区间原则,我们暂且定义, 前者为左区间原则,后者为右区间原则最后在结果集中区分开来
      

  6.   

    为了能尽快解决这个问题,我另开了一个帖子,再送100分,至到解决这个问题。
    http://community.csdn.net/Expert/topic/5532/5532472.xml?temp=.5072443
      

  7.   

    /*以下语句稍作调整,结果中就会出现你所说的同时符合左右区间条件的结果集,这时你可以再加过滤条件来区别到底是优先左区间还是右区间*/CREATE TABLE TabA(ID INT IDENTITY(1,1),ESD SMALLDATETIME,LSD SMALLDATETIME)
    INSERT INTO TabA 
    SELECT '2007-06-01','2007-06-10' UNION ALL
    SELECT '2007-06-05','2007-06-06' UNION ALL
    SELECT '2007-05-31','2007-06-06' UNION ALL
    SELECT '2007-06-05','2007-06-12' UNION ALL
    SELECT '2007-06-05','2007-06-08' 
    --DROP TABLE TabASELECT '左区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,4,B.LSD) = A.LSD
    WHERE A.ID = 1
    UNION ALL
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,-4,B.ESD) = A.ESD
    WHERE A.ID = 1
      

  8.   


    我不知道该如何替换这个部分,来测试 ,因为,你写的中间部分是静态的实例数据,
    实际上我要处理的是 现存的一张表中的数据记录集
    /*SELECT '2007-06-01','2007-06-10' UNION ALL
    SELECT '2007-06-05','2007-06-06' UNION ALL
    SELECT '2007-05-31','2007-06-06' UNION ALL
    SELECT '2007-06-05','2007-06-12' UNION ALL
    SELECT '2007-06-05','2007-06-08' 
    */
      

  9.   

    根据你的实际表字段进行替换,再测试就可以了
    --^_^,我的数据测试也是来自表TabA 啊!~
      

  10.   

    我还是没弄明白,还得麻烦你一下我的理解没错的话 实际上你的 TabA 是 第个语句 生成的在下一个语句中做为数据源表,处理
    但实际上我发现结果不对
    你看以下数据源最后用你的第二个语句得不到正确结果
    ID ESD         LSD
    1   2007-04-20   2007-04-27
    2   2007-04-20   2007-04-27
    3   2007-04-27   2007-05-04
    4   2007-04-23   2007-04-30
    5   2007-03-25   2007-04-01
    6   2007-03-25   2007-04-01
    7   2007-03-25   2007-04-01
      

  11.   

    左区间 1 2007-06-01 00:00:00 2007-06-10 00:00:00 2 2007-06-05 00:00:00 2007-06-06 00:00:00
    左区间 1 2007-06-01 00:00:00 2007-06-10 00:00:00 3 2007-05-31 00:00:00 2007-06-06 00:00:00
    右区间 1 2007-06-01 00:00:00 2007-06-10 00:00:00 2 2007-06-05 00:00:00 2007-06-06 00:00:00
    右区间 1 2007-06-01 00:00:00 2007-06-10 00:00:00 4 2007-06-05 00:00:00 2007-06-12 00:00:00
    右区间 1 2007-06-01 00:00:00 2007-06-10 00:00:00 5 2007-06-05 00:00:00 2007-06-08 00:00:00但根据你的TabA得到的结果是对的,我就不明白了
      

  12.   

    如果A货物的 ESD和LSD 同时在B货物的左区间[ESD-4days,LSD-4days]内,我们就将A,B识为
    满足区间原则 
       或者
    如果A货物的 ESD和LSD 同时在B货物的右区间[ESD+4days,LSD+4days]内,我们也将A,B识为
    满足区间原则 你这样说,我也糊涂了,我的需求有什地方让你觉得混消吗? 
    请你直接说吧。 我希望能更清楚向你解释
      

  13.   

    CREATE TABLE TabA(ID INT IDENTITY(1,1),ESD SMALLDATETIME,LSD SMALLDATETIME)
    INSERT INTO TabA 
    SELECT '2007-04-20','2007-04-27' UNION ALL
    SELECT '2007-04-20','2007-04-27' UNION ALL
    SELECT '2007-04-27','2007-05-04' UNION ALL
    SELECT '2007-04-23','2007-04-30' UNION ALL
    SELECT '2007-03-25','2007-04-01' UNION ALL 
    SELECT '2007-03-25','2007-04-01' UNION ALL 
    SELECT '2007-03-25','2007-04-01'
    --DROP TABLE TabASELECT '左区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,4,B.ESD) = A.ESD OR DATEADD(DAY ,4,B.LSD) = A.LSD
    --WHERE A.ID = 3
    UNION ALL
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,-4,B.ESD) = A.ESD OR DATEADD(DAY ,-4,B.LSD) = A.LSD
    --WHERE A.ID = 3
    -----------------------------------------------
    结果集:(表明第3条的最区间包含4,或4的有区间包含3.只有这两条成立,其中的语句你可以自己调整试一下,应该和你表述的意思差不多了)
    左区间
    1 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL 左区间
    2 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL 左区间
    3 2007-04-27 00:00:00 2007-05-04 00:00:00 4 2007-04-23 00:00:00 2007-04-30 00:00:00 左区间
    4 2007-04-23 00:00:00 2007-04-30 00:00:00 NULL NULL NULL 左区间
    5 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL 左区间
    6 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL 左区间
    7 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL 右区间
    1 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL 右区间
    2 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL 右区间
    3 2007-04-27 00:00:00 2007-05-04 00:00:00 NULL NULL NULL 右区间
    4 2007-04-23 00:00:00 2007-04-30 00:00:00 3 2007-04-27 00:00:00 2007-05-04 00:00:00 右区间
    5 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL 右区间
    6 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL 右区间
    7 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL
      

  14.   

    CREATE TABLE TabA(ID INT IDENTITY(1,1),ESD SMALLDATETIME,LSD SMALLDATETIME)
    INSERT INTO TabA 
    SELECT '2007-04-20','2007-04-27' UNION ALL
    SELECT '2007-04-20','2007-04-27' UNION ALL
    SELECT '2007-04-27','2007-05-04' UNION ALL
    SELECT '2007-04-23','2007-04-30' UNION ALL
    SELECT '2007-03-25','2007-04-01' UNION ALL 
    SELECT '2007-03-25','2007-04-01' UNION ALL 
    SELECT '2007-03-25','2007-04-01'
    --DROP TABLE TabASELECT '左区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,4,B.ESD) = A.ESD OR DATEADD(DAY ,4,B.LSD) = A.LSD
    --WHERE A.ID = 3
    UNION ALL
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,-4,B.ESD) = A.ESD OR DATEADD(DAY ,-4,B.LSD) = A.LSD
    --WHERE A.ID = 3
    -----------------------------------------------
    结果集:(表明第3条的最区间包含4,或4的有区间包含3.只有这两条成立,其中的语句你可以自己调整试一下,应该和你表述的意思差不多了)
    左区间 1 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL
    左区间 2 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL
    左区间 3 2007-04-27 00:00:00 2007-05-04 00:00:00 4 2007-04-23 00:00:00 2007-04-30 00:00:00
    左区间 4 2007-04-23 00:00:00 2007-04-30 00:00:00 NULL NULL NULL
    左区间 5 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL
    左区间 6 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL
    左区间 7 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL
    右区间 1 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL
    右区间 2 2007-04-20 00:00:00 2007-04-27 00:00:00 NULL NULL NULL
    右区间 3 2007-04-27 00:00:00 2007-05-04 00:00:00 NULL NULL NULL
    右区间 4 2007-04-23 00:00:00 2007-04-30 00:00:00 3 2007-04-27 00:00:00 2007-05-04 00:00:00
    右区间 5 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL
    右区间 6 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL
    右区间 7 2007-03-25 00:00:00 2007-04-01 00:00:00 NULL NULL NULL
      

  15.   

    结果集:(表明第3条的最区间包含4,或4的有区间包含3.只有这两条成立,其中的语句你可以自己调整试一下,应该和你表述的意思差不多了)
    左区间12007-04-20 00:00:002007-04-27 00:00:00NULLNULLNULL
    左区间22007-04-20 00:00:002007-04-27 00:00:00NULLNULLNULL
    左区间32007-04-27 00:00:002007-05-04 00:00:0042007-04-23 00:00:002007-04-30 00:00:00
    左区间42007-04-23 00:00:002007-04-30 00:00:00NULLNULLNULL
    左区间52007-03-25 00:00:002007-04-01 00:00:00NULLNULLNULL
    左区间62007-03-25 00:00:002007-04-01 00:00:00NULLNULLNULL
    左区间72007-03-25 00:00:002007-04-01 00:00:00NULLNULLNULL
    右区间12007-04-20 00:00:002007-04-27 00:00:00NULLNULLNULL
    右区间22007-04-20 00:00:002007-04-27 00:00:00NULLNULLNULL
    右区间32007-04-27 00:00:002007-05-04 00:00:00NULLNULLNULL
    右区间42007-04-23 00:00:002007-04-30 00:00:0032007-04-27 00:00:002007-05-04 00:00:00
    右区间52007-03-25 00:00:002007-04-01 00:00:00NULLNULLNULL
    右区间62007-03-25 00:00:002007-04-01 00:00:00NULLNULLNULL
    右区间72007-03-25 00:00:002007-04-01 00:00:00NULLNULLNULL
    =======================================
    其实这两个满足条件的记录是重复的, 因为它们有相同的一对ID,只需要保留一个就可以了
    ,另外我有些不明白 
     WHERE A.ID = 3    //这里为什么要指定这个特定的条件呢?
      

  16.   

    CREATE TABLE TabA(ID INT IDENTITY(1,1),ESD SMALLDATETIME,LSD SMALLDATETIME)
    INSERT INTO TabA 
    SELECT '2007-04-20','2007-04-27' UNION ALL
    SELECT '2007-04-20','2007-04-27' UNION ALL
    SELECT '2007-04-27','2007-05-04' UNION ALL
    SELECT '2007-04-23','2007-04-30' UNION ALL
    SELECT '2007-03-25','2007-04-01' UNION ALL 
    SELECT '2007-03-25','2007-04-01' UNION ALL 
    SELECT '2007-03-25','2007-04-01'
    --DROP TABLE TabASELECT '左区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,4,B.ESD) = A.ESD OR DATEADD(DAY ,4,B.LSD) = A.LSD
    UNION ALL
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,-4,B.ESD) = A.ESD OR DATEADD(DAY ,-4,B.LSD) = A.LSD-------------------------------------------------------------------------------
    /*
    其实这两个满足条件的记录是重复的, 因为它们有相同的一对ID,只需要保留一个就可以了
    ----我显示出来的是一个全结果集,也就是包含或满足左区间或满足右区间的结果集,你只需要按你需要的内容再加过滤条件就可以了---------------------------------------------------------------
    另外我有些不明白  WHERE A.ID = 3    //这里为什么要指定这个特定的条件呢?
    ---- 只是为了说明ID为3的记录包含的符合条件的记录
    */
      

  17.   

    结果还是不对
    如上面的数据中至少
     '2007-04-20','2007-04-27' 
     '2007-04-20','2007-04-27' 也应该在同一个区间 (这种情况比较特别,
     当两票货的时间完全一样时,它们同时都在对方的左右区间内,且重叠为4days)
    逻辑也有问题
    如:
    ON DATEADD(DAY ,4,B.ESD) = A.ESD OR DATEADD(DAY ,4,B.LSD) = A.LSD
    第一> 这里只考虑了边界点,没有考虑范围,更没有考虑重叠区域的大小 --4days
     eg : [4/23             4/30]
          |___________________|
                    |
                    |___________________|
                   [4/27                 5/4]
      这两票货本身就有4days (4/27,4/28,4/29,4/30)的重叠,自然在至少有一个区间是重叠的.
      但您的查询得不到
    ==============================
    这个问题还是没有得到正确答案,希望更多的朋友一起来解答,集思广义
     
                 
      

  18.   

    逻辑也有问题
    如:
    ON DATEADD(DAY ,4,B.ESD) = A.ESD OR DATEADD(DAY ,4,B.LSD) = A.LSD
    第一> 这里只考虑了边界点,没有考虑范围,更没有考虑重叠区域的大小 --4days
     eg : [4/23             4/30]
          |___________________|
                    |
                    |___________________|
                   [4/27                 5/4]
    -----------------------------------------------------------
    DATEADD(DAY ,4,B.ESD) = A.ESD OR DATEADD(DAY ,4,B.LSD) = A.LSD只是我根据你开始提出的问题及要求结果而做的查询条件! 当边界点确定并且没有问题的时候,你只需要根据边界点来加一个范围的条件就可以了
      

  19.   

    ID = 1: '2007-04-20','2007-04-27'
    ID = 2: '2007-04-21','2007-04-27'
    ID = 3: '2007-04-22','2007-04-27'
    ID = 4: '2007-04-23','2007-04-27'
    ID = 5: '2007-04-24','2007-04-27'
    如果你要的结果是 ID = 2,3,4,5 都是 ID = 1的有效右区间数据:那么
    --Try
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON ABS(DATEDIFF(DAY,A.ESD,B.ESD)) <= 4
    --如果和你的意思,就用同样的办法来处理右区间
      

  20.   

    to: simonhehe(流氓会武术,谁也挡不住) 
    您说得一点都没错,我后来就是按您所说的哪样改为了
    SELECT '左区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,3,B.ESD) >= A.ESD and DATEADD(DAY ,3,B.LSD) >= A.LSD
    WHERE A.ID!=B.ID
    UNION ALL
    SELECT '右区间',* FROM TabA A LEFT OUTER JOIN TabA B ON DATEADD(DAY ,-3,B.ESD) <= A.ESD and DATEADD(DAY ,-3,B.LSD) <= A.LSD 
    WHERE B.ID!=A.ID看到了好象离我要的不远了,但是哪些重复的项我始终不知道如何处掉,没办法,不会就是不会。
    我在 http://community.csdn.net/Expert/topic/5532/5532472.xml?temp=.2059137
    中根据您提供的 思路和测试的结果 重新整理了一个我最终的的需求
    大致和现在的需求没有太多区别, 您不防再看看,我想您可以很快解决的谢谢
      

  21.   

    to :simonhehe(流氓会武术,谁也挡不住) 
    更正一个小地方: 哪就是 
    中间区间[ESD,LSD]
    左区间[ESD-3,LSD-3]
    右区间[ESD+3,LSD+3] 
    因为重叠4天,边界+ 3天刚好=4天