2012-02-22 149 views
1

我有一个表包含很多列,我必须根据这两列,使我的选择:困难SQL查询

TIME ID 
-216 AZA 
215 AZA 
    56 EA 
-55 EA 
    66 EA 
-03 AR 
    03 OUI 
-999 OP 
999 OP 
    04 AR 
    87 AR 

预期输出是

TIME ID 
    66 EA 
    03 OUI 
    87 AR 

我需要选择行没有匹配。有些行具有相同的ID,几乎同一时间,但有一点区别。例如,TIME -216的第一行与时间215的第二条记录相匹配。我试图用多种方式解决它,但是每当我发现自己迷路了。

+1

请编辑您的文章,而不是强调行,添加一个单独的表,将构成预期的输出,以避免任何含糊不清。 – 2012-02-22 08:17:00

+2

你的问题目前还不清楚。 – 2012-02-22 08:17:29

+0

此外,此表是否有主键?或者至少'TIME'是独一无二的? – 2012-02-22 08:17:55

回答

2

第一步 - 查找具有重复ID的行。第二步 - 对接近反向重复的行进行过滤。

第一步:

SELECT t1.TIME, t2.TIME, t1.ID FROM mytable t1 JOIN mytable 
t2 ON t1.ID = t2.ID AND t1.TIME > t2.TIME; 

的连接语句的第二部分,确保我们只得到一个记录的一对。

第二步:

SELECT t1.TIME,t2.TIME,t1.ID FROM mytable t1 JOIN mytable t2 ON t1.ID = t2.ID AND 
t1.TIME > t2.TIME WHERE ABS(t1.TIME + t2.TIME) < 3; 

这将产生,例如如果一些重复的结果。 (10, FI), (-10, FI) and (11, FI)在您的表中,因为有两个有效的对。您可以按以下方式筛选出来:

SELECT t1.TIME,MAX(t2.TIME),t1.ID FROM mytable t1 JOIN mytable t2 ON 
t1.ID = t2.ID AND t1.TIME > t2.TIME WHERE ABS(t1.TIME + t2.TIME) < 3 GROUP BY 
t1.TIME,t1.ID; 

但是您不清楚您想要放弃哪个结果。不过希望这会让你指向正确的方向!

+0

只有一张表,联结从哪里来? – Mansuro 2012-02-22 08:33:15

+0

@Mansuro其自身加入 – joshua 2012-02-22 08:38:49

+0

@Madhav啊对不起,愚蠢的问题,我没看好 – Mansuro 2012-02-22 08:42:30

0

这有帮助吗?

create table #RawData 
(
    [Time] int, 
    ID varchar(3) 
) 

insert into #rawdata ([time],ID) 
select -216, 'AZA' 
union 
select 215, 'AZA' 
union 
select 56, 'EA' 
union 
select -55, 'EA' 
union 
select 66, 'EA' 
union 
select -03, 'AR' 
union 
select 03, 'OUI' 
union 
select -999, 'OP' 
union 
select 999, 'OP' 
union 
select 04, 'AR' 
union 
select 87, 'AR' 
union 
-- this value added to illustrate that the algorithm does not ignore this value 
select 156, 'EA' 

--create a copy with an ID to help out 
create table #Data 
(
    uniqueId uniqueidentifier, 
    [Time] int, 
    ID varchar(3) 
) 

insert into #Data(uniqueId,[Time],ID) select newid(),[Time],ID from #RawData 
declare @allowedDifference int 
select @allowedDifference = 1 
--find duplicates with matching inverse time 
select *, d1.Time + d2.Time as pairDifference from #Data d1 inner join #Data d2 on d1.ID = d2.ID and (d1.[Time] + d2.[Time] <[email protected] and d1.[Time] + d2.[Time] >= (-1 * @allowedDifference)) 

-- now find all ID's ignoring these pairs 
select [Time],ID from #data 
where uniqueID not in (select d1.uniqueID from #Data d1 inner join #Data d2 on d1.ID = d2.ID and (d1.[Time] + d2.[Time] <=3 and d1.[Time] + d2.[Time] >= -3))