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 神奇语句 找出所有 有相同区间的数据
我头有点大了 , 谁能帮我 ???!!
在线侯教
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 神奇语句 找出所有 有相同区间的数据
我头有点大了 , 谁能帮我 ???!!
在线侯教
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
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
您的测试结果是对的,但问题好象没有哪么简单我们可以看出每条记录都有 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识为
满足区间原则 我的问题就时要找出满足区间原则的数据集也许我这样描述会更清楚一些这个问题,我实在是没法独立解决,希望大家帮帮忙
满足区间原则
或者
如果A货物的 ESD和LSD 同时在B货物的右区间[ESD+4days,LSD+4days]内,我们也将A,B识为
满足区间原则 为了区分这两种区间原则,我们暂且定义, 前者为左区间原则,后者为右区间原则最后在结果集中区分开来
http://community.csdn.net/Expert/topic/5532/5532472.xml?temp=.5072443
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
我不知道该如何替换这个部分,来测试 ,因为,你写的中间部分是静态的实例数据,
实际上我要处理的是 现存的一张表中的数据记录集
/*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'
*/
--^_^,我的数据测试也是来自表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
左区间 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得到的结果是对的,我就不明白了
满足区间原则
或者
如果A货物的 ESD和LSD 同时在B货物的右区间[ESD+4days,LSD+4days]内,我们也将A,B识为
满足区间原则 你这样说,我也糊涂了,我的需求有什地方让你觉得混消吗?
请你直接说吧。 我希望能更清楚向你解释
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
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
左区间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 //这里为什么要指定这个特定的条件呢?
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的记录包含的符合条件的记录
*/
如上面的数据中至少
'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)的重叠,自然在至少有一个区间是重叠的.
但您的查询得不到
==============================
这个问题还是没有得到正确答案,希望更多的朋友一起来解答,集思广义
如:
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只是我根据你开始提出的问题及要求结果而做的查询条件! 当边界点确定并且没有问题的时候,你只需要根据边界点来加一个范围的条件就可以了
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
--如果和你的意思,就用同样的办法来处理右区间
您说得一点都没错,我后来就是按您所说的哪样改为了
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
中根据您提供的 思路和测试的结果 重新整理了一个我最终的的需求
大致和现在的需求没有太多区别, 您不防再看看,我想您可以很快解决的谢谢
更正一个小地方: 哪就是
中间区间[ESD,LSD]
左区间[ESD-3,LSD-3]
右区间[ESD+3,LSD+3]
因为重叠4天,边界+ 3天刚好=4天