SQL Server中的联合与联接
我的SQL代码执行以下操作:它获取所有文本,其中O_Top-previous O_Top<30,O_Left-previous O_Left<100 表中的数据如下:SQL Server中的联合与联接,sql,sql-server-2008,join,union,Sql,Sql Server 2008,Join,Union,我的SQL代码执行以下操作:它获取所有文本,其中O_Top-previous O_Top
Text O_Top O_Left
------------------------------
D 536 654
5 401 544
1 392 581
2 395 609
K 418 666
1 329 142
K 421 711
H 424 753
9 228 1194
5 205 666
SQL代码:
;WITH cte AS
(
SELECT
[Text], [O_Top], [O_Left],
ID = ROW_NUMBER() OVER (ORDER BY [O_Left])
FROM
MyTableName
)
SELECT *
FROM cte AS c1
LEFT JOIN CTE c2 ON c1.ID = C2.ID - 1
WHERE ABS(c1.O_Top - c2.O_Top) < 30
AND ABS(C1.O_Left - c2.O_Left) < 110
ORDER BY C1.[O_Left]
我期待do like UNION的结果如下:
Text O_Top O_Left ID
---------------------------
5 401 544 2
1 392 581 3
K 418 666 7
K 421 711 8
1 392 581 3
2 395 609 4
K 421 711 8
H 424 753 9
我正在寻找一种避免重复列的方法,如果我能在同一个SQL命令中使用类似distinct的东西,那么我会非常惊讶,因为现在重复的ID是8和3
我试着想了很多,但我觉得命令太复杂了,我的大脑无法处理它
非常感谢您的帮助和支持 您可以通过对当前CTE的联合查询来实现所需。尝试此操作,请参见下面的说明:
WITH cte2 AS (
SELECT
c1.Text AS Text1, c1.O_Top AS O_Top1, c1.O_Left AS O_Left1, c1.ID AS ID1,
c2.Text AS Text2, c2.O_Top AS O_Top2, c2.O_Left AS O_Left2, c2.ID AS ID2
FROM cte AS c1
LEFT JOIN cte c2
ON c1.ID = c2.ID - 1
WHERE ABS(c1.O_Top - c2.O_Top) < 30 AND
ABS(c1.O_Left - c2.O_Left) < 110
),
cte3 AS (
SELECT
Text1 AS Text, O_Top1 AS O_Top, O_Left1 AS O_Left, ID1 AS ID, 1 AS pos
FROM cte2
UNION ALL
SELECT
Text2, O_Top2, O_Left2, ID2, 2
FROM cte2
)
SELECT *
FROM cte3
ORDER BY
pos,
O_Left
为了实现这一点,我做了以下更改:
为原始CTE中的两组列使用显式别名
在cte3联合查询中添加了一个计算列,以跟踪正在选择的值集
使用上面的计算列从cte3中选择,以您想要的方式对记录进行排序
在查询中,您只需在cte之间的自连接条件上添加或c1.ID=C2.ID+1,然后仅从c1中选择。这样可以同时比较上一行和下一行。如果您希望获得独特的结果,请添加distinct
;With cte as
(Select [Text],[O_Top],[O_Left], ID = Row_Number() over(order bY [O_Left])
from MyTableName)
Select distinct c1.*
from cte as c1
left Join cte c2
on c1.ID = C2.ID - 1 OR c1.ID = C2.ID +1
where ABS(c1.O_Top - c2.O_Top) < 30
and ABS(C1.O_Left - c2.O_Left) < 110
order bY C1.[O_Left]
或者将两个or条件替换为ABSc1.ID-C2.ID=1我看不到数据和查询之间的关系。但是,如果要取消打印结果,可以使用交叉应用:
非常感谢你,我正在尝试,我会告诉你:神奇是完美的:D,我能知道这个额外的字段pos是如何工作的吗?字段pos是一个计算列,我们添加它来跟踪记录的来源。您可以通过其工作方式查看外部顺序。旁注:您的示例值与结果表中的值不匹配。是的,您是对的。很抱歉,我现在会尝试编辑它谢谢你的添加,这是我第一次知道交叉申请
;With cte as
(Select [Text],[O_Top],[O_Left], ID = Row_Number() over(order bY [O_Left])
from MyTableName)
Select distinct c1.*
from cte as c1
left Join cte c2
on c1.ID = C2.ID - 1 OR c1.ID = C2.ID +1
where ABS(c1.O_Top - c2.O_Top) < 30
and ABS(C1.O_Left - c2.O_Left) < 110
order bY C1.[O_Left]
With cte as (
Select [Text],[ O_Top], [O_Left],
ID = Row_Number() over(order bY [O_Left])
from MyTableName
)
Select v.*
from cte c1 left join
cte c2
on c1.ID = C2.ID - 1 cross apply
(values (c1.[Text], c1.O_Top, c1.O_Left, c1.id),
(c2.[Text], c2.O_Top, c2.O_Left, c2.id)
) v([Text], O_Top, O_Left, id)
where ABS(c1.O_Top - c2.O_Top) < 30 and
ABS(C1.O_Left - c2.O_Left) < 110;