用于在SQL Server数据库中提取匹配对角线对的SQL查询

qv7cva1a  于 2022-11-28  发布在  SQL Server
关注(0)|答案(1)|浏览(138)

我有一个数据库表(mytable),它有2列xy,如下所示,我打算从中提取具有匹配对角线对(x,y)和(y,x)的行,例如4 21和21 4

x  y
86 86
27 27
45 45
95 95
11 11
18 8
85 85
2 2
77 77
91 91
15 15
84 84
51 51
32 32
35 35
8 8
92 92
67 67
62 62
33 33
13 13
15 11
18 18
3 3
38 38
80 80
34 34
6 6
72 72
14 12
44 44
4 22
90 90
47 47
78 78
23 3
42 42
56 56
79 79
55 55
65 65
17 17
64 64
4 4
28 28
19 19
17 9
36 36
25 25
81 81
60 60
48 48
5 5
88 88
7 19
21 21
29 29
52 52
9 17
9 9
13 13
16 10
1 1
31 31
46 46
7 7
58 58
23 23
87 87
83 83
66 66
93 93
24 2
98 98
53 53
20 6
61 61
20 20
96 96
99 99
73 73
2 24
14 14
71 71
5 21
22 4
75 75
6 20
97 97
41 41
26 26
22 22
8 18
74 74
40 40
21 5
94 94
76 76
49 49
11 15
59 59
89 89
68 68
24 24
37 37
12 12
63 63
43 43
16 16
100 100
39 39
25 1
69 69
54 54
50 50
30 30
10 10

我已经在我的mytable上尝试了这里的stackoverflow(enter link description here)上的可接受代码,它在Oracle DB上给了我预期的结果。

select least(x, y) as x, greatest(x, y) as y
from mytable
group by least(x, y), greatest(x, y)
having count(*) = 2
union all
select x, y
from mytable
where not exists (select 1 from mytable mytable2 where mytable2.y = mytable.x and mytable2.x = mytable2.y)
order by x asc;

现在我需要在MS SQL DB上执行相同的查询,但根据我的理解,MS SQL DB不支持最小和最大函数。我尝试使用case条件,例如,对于提供的链接上的SQL查询的第一部分,我正在考虑以下内容,但到目前为止,我无法复制类似的结果:

select x,y,z
from (
select x, y,
case 
    when (x < y) then x
    when (y > x) then y
end as z
from mytable
group by x, y
) as t

在SQL Server数据库中完成查询需要考虑哪些因素,以便生成如下所示的最终输出,对此有何建议?
如果有人能告诉我如何使用SQL的lag()函数来帮助我达到同样的结果,那就太好了。

;with t1 as (
select x as x1, y as y1, lag(x,1) over(order by x asc) as z1
from mytable
),
t2 as (
select x as x2, y as y2, lag(y,1) over(order by x asc) as z2
from mytable
)
select t1.*,t2.*
from t1 full outer join t2 on t1.x1 = t2.x2

预期输出

x y
2 24
4 22
5 21
6 20
8 18
9 17
11 15
13 13
trnvg8h3

trnvg8h31#

函数LEAST()GREATEST()的等效用法是使用CASE表达式:

SELECT CASE WHEN x < y THEN x ELSE y END AS x, 
       CASE WHEN x > y THEN x ELSE y END AS y
FROM mytable
GROUP BY CASE WHEN x < y THEN x ELSE y END, 
         CASE WHEN x > y THEN x ELSE y END
HAVING COUNT(*) = 2 -- change to COUNT(*) > 1 if each combination may exist more than twice
ORDER BY x, y;

上述查询将返回(x, y)组合的一行,该组合存在两次,即使(y, x)不存在。
如果这不是您想要的,请使用自我链接和UNION ALL

SELECT DISTINCT t1.*
FROM mytable t1 INNER JOIN mytable t2
ON t2.x = t1.y AND t2.y = t1.x
WHERE t1.x < t1.y
UNION ALL
SELECT x, y
FROM mytable
WHERE x = y
GROUP BY x, y
HAVING COUNT(*) > 1
ORDER BY x, y;

请参阅demo

相关问题