SQL Anywhere:查找与另一行相比为+-2的行

SQL Anywhere:查找与另一行相比为+-2的行,sql,sybase,sqlanywhere,Sql,Sybase,Sqlanywhere,我有下表: ID User Form Depth 1 A ABC 2001 1 A XYZ 1001 1 B XYZ 1003 1 B DEF 3001 1 C XYZ 1000 如果ID和Form是相同的,我需要从用户A中识别那些是+-2的行。使用上面的示例,脚本将返回: ID User Form Depth 1 B XYZ 1003 1 C XYZ 1000 我已经

我有下表:

ID  User  Form  Depth
1   A     ABC   2001
1   A     XYZ   1001
1   B     XYZ   1003
1   B     DEF   3001
1   C     XYZ   1000
如果ID和Form是相同的,我需要从用户A中识别那些是+-2的行。使用上面的示例,脚本将返回:

ID  User  Form  Depth
1   B     XYZ   1003
1   C     XYZ   1000
我已经有了一个脚本,可以识别具有相同ID和形式的行——我只需要另一部分,但我正在努力弄清楚逻辑。我希望有一种DIFF函数可以使用,但是我在任何地方都找不到一种适合SQL的函数

有人有什么建议吗

谢谢

我想你想要的是:


如果您希望深度与A的深度正好为+/-2:

select t1.*
from   mytab t1,
       mytab t2
where  t1.id    = t2.id
and    t1.form  = t2.form
and    t1.user != 'A'
and    t2.user  = 'A'
and    abs(t1.depth - t2.depth) = 2
go

ID  User  Form  Depth
--- ----- ----- -----
1   B     XYZ   1003

如果您希望深度在A深度的2以内,即,diff是一种快速且肮脏的通用方法

将@User替换为要删除的人

DECLARE @table TABLE ( 
    ID Int
    ,[User] VARCHAR(2) 
    ,Form VARCHAR(3)
    ,Depth INT 
) 

DECLARE @User VARCHAR(2) = 'A' 

INSERT INTO @table (ID , [User], Form, Depth)
VALUES 
    (1 , 'A' , 'ABC' , 2001),
    (1 , 'A' , 'XYZ' , 1001),
    (1 , 'B' , 'XYZ' , 1003),
    (1 , 'B' , 'DEF' , 3001),
    (1 , 'C' , 'XYZ' , 1000)

SELECT t1.ID, t1.[User], t1.Form, t1.Depth , ROW_NUMBER() OVER(ORDER BY t1.ID, t1.[User], t1.Form, t1.Depth) AS [row_number] 
INTO #temp 
FROM @table as t1 
INNER JOIN ( 
    SELECT t.ID, t.Form, COUNT('8') as [count] 
    FROM @table as t
    GROUP BY ID, Form 
    HAVING COUNT('8') > 1 
) as duplicates
ON duplicates.ID = t1.ID 
AND duplicates. Form = t1.Form 
ORDER BY ID, User, Form, Depth


-- SELECT * FROM #temp 

SELECT [row_number] - 2 as value 
INTO #range 
FROM #temp as t
WHERE t.[User] = @User


--SELECT * FROM #range

INSERT INTO #range 
SELECT [row_number] - 1 
FROM #temp as t 
WHERE t.[User] = @User

INSERT INTO #range 
SELECT [row_number] + 1 
FROM #temp as t
WHERE t.[User] = @User

INSERT INTO #range 
SELECT [row_number] + 2
FROM #temp as t 
WHERE t.[User] = @User

SELECT * FROM #temp 
WHERE [row_number] IN (SELECT value FROM #range)


DROP TABLE #temp 
DROP TABLE #range 

行应该如何排序?到目前为止您尝试了什么SQL?为什么输出中没有1,A,XYZ,1001。。。或者用户是否有其他要求!='A'?如果User='A'有两个条目,但深度不同,该怎么办?对于一个diff-like函数。。。考虑ABS…我会让这一个沉入一点…结果顺序没有太大的区别,因为我正在构建这个脚本来删除它们。基本上,如果A和B或A和C之间的方差大于或小于2,它们将保持不变;否则,B和C将被删除,希望这是有意义的。到目前为止,我仅有的SQL是用于查找相同ID和表单的脚本—我似乎找不到对我有意义的脚本逻辑。我不希望返回用户A。您可以使用ROW_NUMBER和OVER函数来执行此操作。您需要指定订单。非常感谢您,Markp!这正是我想要的。
select t1.*
from   mytab t1,
       mytab t2
where  t1.id    = t2.id
and    t1.form  = t2.form
and    t1.user != 'A'
and    t2.user  = 'A'
and    abs(t1.depth - t2.depth) <= 2
go

ID  User  Form  Depth
--- ----- ----- -----
1   B     XYZ   1003
1   C     XYZ   1000
DECLARE @table TABLE ( 
    ID Int
    ,[User] VARCHAR(2) 
    ,Form VARCHAR(3)
    ,Depth INT 
) 

DECLARE @User VARCHAR(2) = 'A' 

INSERT INTO @table (ID , [User], Form, Depth)
VALUES 
    (1 , 'A' , 'ABC' , 2001),
    (1 , 'A' , 'XYZ' , 1001),
    (1 , 'B' , 'XYZ' , 1003),
    (1 , 'B' , 'DEF' , 3001),
    (1 , 'C' , 'XYZ' , 1000)

SELECT t1.ID, t1.[User], t1.Form, t1.Depth , ROW_NUMBER() OVER(ORDER BY t1.ID, t1.[User], t1.Form, t1.Depth) AS [row_number] 
INTO #temp 
FROM @table as t1 
INNER JOIN ( 
    SELECT t.ID, t.Form, COUNT('8') as [count] 
    FROM @table as t
    GROUP BY ID, Form 
    HAVING COUNT('8') > 1 
) as duplicates
ON duplicates.ID = t1.ID 
AND duplicates. Form = t1.Form 
ORDER BY ID, User, Form, Depth


-- SELECT * FROM #temp 

SELECT [row_number] - 2 as value 
INTO #range 
FROM #temp as t
WHERE t.[User] = @User


--SELECT * FROM #range

INSERT INTO #range 
SELECT [row_number] - 1 
FROM #temp as t 
WHERE t.[User] = @User

INSERT INTO #range 
SELECT [row_number] + 1 
FROM #temp as t
WHERE t.[User] = @User

INSERT INTO #range 
SELECT [row_number] + 2
FROM #temp as t 
WHERE t.[User] = @User

SELECT * FROM #temp 
WHERE [row_number] IN (SELECT value FROM #range)


DROP TABLE #temp 
DROP TABLE #range