我需要给两张表(两组)的交叉连接(交叉产品)所产生的任何一行提供一个唯一的标识符。基本上,我需要将结果集中的任何一行的列值 "浓缩 "在一个唯一的标识符中。我想用GUID方法或类似的方法,但我不确定它是否能达到目的。什么方法可以在SQL Sserver上有效?这个机制的目的是评估不同集(表)的所有可能的成员(行)组合,并为以后需要使用的任何组合分配一个唯一的名称。
例子
Input Tables A and B
+----+----+ +----+----+
| Table A | | Table B |
+----+----+ +----+----+
| A1 | A2 | | B1 | B2 |
+----+----+ +----+----+
| 1 | 2 | | a | b |
| 3 | 4 | | c | d |
+----+----+ +----+----+
结果集表A X B +唯一标识符
+----+----+----+----+ +-----+
| A1 | A2 | B1 | B2 | | UID |
+----+----+----+----+ +-----+
| 1 | 2 | a | b | | 001 |
| 1 | 2 | c | d | | 002 |
| 3 | 4 | a | b | | 003 |
| 3 | 4 | c | d | | 004 |
+----+----+----+----+ +-----+
一个选项是使用 row_number()
:
select
a.a1,
a.a2,
b.b1,
b.b2,
row_number() over(order by a.a1, a.a2, b.b1, b.b2) uid
from a
cross join b
如果你想要一个长期一致的唯一标识符,那么就把表中的两个标识符结合起来。
concat(a1, ':', b1)
这样做的前提是: a1
和 b1
是主键。
如果你没有主键,那就添加一个。 这样会方便你想做的事情。
你可以冒险使用哈希函数。 像这样的。
select concat(convert(varchar(32), hashbytes('MD5', concat(a1, ':', a2), 2), ':',
convert(varchar(32), hashbytes('MD5', concat(b1, ':', b2), 2)
)
这样做会有碰撞的风险 (即使底层值不一样,但散列值也是一样的),但这是很低的。 这是使用主键的一个论据。