2012-02-22 105 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))