SQL 任意位置:查找与另一行相比 +-2 的行

SQL Anywhere: find rows that are +-2 compared to another row

我有以下 table:

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 和表单相同,我需要从用户 A 中识别出那些 +-2 的行。使用上面的示例,脚本将 return:

ID  User  Form  Depth
1   B     XYZ   1003
1   C     XYZ   1000

我已经有一个脚本可以识别具有相同 ID 和表单的行——我只需要另一部分,但我正在努力弄清楚其中的逻辑。我希望有某种我可以使用的 DIFF 函数,但我找不到 SQL Anywhere.

有人有什么建议吗?

谢谢!

我想你想要 exists:

select t.*
from t
where t.user <> 'A' and
      exists (select 1
              from t t2
              where t2.form = t.form and t2.id = t.id and
                    t2.depth between t.depth - 2 and t.depth + 2
             );

如果您要查找的深度恰好是 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 <= 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
1   C     XYZ   1000

这是非常基本的 SQL,所以虽然 fiddle 是用 MySQL 完成的,但您应该会发现查询在 SQLAnywhere 中也有效:sql fiddle

一种快速而肮脏的通用方法。

@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