从相同的 ID 集中生成相同的 ID
本文关键字:ID 集中 | 更新日期: 2023-09-27 18:37:11
我有一个问题,我会尝试解释。我的想法是用 C# 在 SSIS 中创建一个脚本,并用该脚本为表中每个唯一的 ID 组合生成 ID 列表。
我有一个由两列组成的SQL服务器表。这些列是 ID(我可以将它们设为数字,但在原始格式中它们是字母数字字符串)。我想从第 2 列中连接到第 1 列的 ID 集中生成一个新 ID。
Col1 Col2 Generated ID
1 1
1 2 => 1
1 3
-----------
2 1 => 2
2 3
-----------
3 3
3 1 => 1
3 2
我正在考虑哈希函数?但是,如何从 1 和 3 的集合中获取相同的 ID?独立于秩序?我需要先对它们进行排序吗?
我需要"10 声誉"来发布图像,所以我希望我的插图能解释这个问题......
作为尝试理解您的问题的进一步示例,您是否希望 Col2 中的以下值集返回类似"123"的内容作为下面列出的所有情况的"生成的 ID"值,如下所示?
Col2 => 生成的 ID
1,2,3 => 123
1,3,2 => 123
2,1,3 => 123
2,3,1 => 123
3,1,2 => 123
3,2,1 => 123
等
如果是这样,那么基于上述假设并回答您的问题:
- 是的,哈希函数可以做到这一点
- 如何为集合 1 和 3(在您的示例中)获得相同的"生成 ID"将取决于您的 GetHashCode() 覆盖/实现
- 是的,您可能需要排序,但同样,这取决于您的实现。
由于您指的是在 SSIS 中使用 C# 脚本,因此可能的 C# 实现可能是实现一个(非常!)简单的 Hash 类,该类给定一组 Col2 值(针对每个数据集),只需:
- 对 Col2 的值进行排序,以使其按"正确"顺序获取,并且
- 返回排序数据集的一些整数表示形式以获取哈希(例如,将 int 连接为字符串,然后转换回 int)
哈希类可以在(基?)类的 GetHashCode() 函数中实例化,该函数传递 Col2 值并执行上述步骤 (1) 和 (2),根据需要返回哈希代码。
类似这样的东西可能适合你(假设你有权访问你正在使用的 .NET 版本中的泛型):
namespace SimpleHashNamespace
{
public class SimpleHash
{
private readonly List<int> _data;
public SimpleHash(List<int> col2)
{
_data = col2;
}
public int GetMyHash()
{
_data.Sort();
string stringHash = string.Join("", _data);
return int.Parse(stringHash); // warning 1: assumes you always have a convertible value
}
}
public class MyDataSet
{
private readonly List<int> _dataSetValues;
public MyDataSet(List<int> dataSetValues)
{
_dataSetValues = dataSetValues;
}
public override int GetHashCode()
{
SimpleHash simpleHash = new SimpleHash(_dataSetValues);
return simpleHash.GetMyHash(); // warning 2: assumes the computed hash can fit into the int datatype given that GetHashCode() has to return int
}
}
public partial class Program
{
private static void Main(string[] args)
{
// how you split up Col1 to get your list of int's dataset is up to you
var myDataSet1 = new MyDataSet(new List<int>(new int[] { 1,2,3 }));
Console.WriteLine(myDataSet1.GetHashCode());
var myDataSet2 = new MyDataSet(new List<int>(new int[] { 2,1,3 }));
Console.WriteLine(myDataSet2.GetHashCode());
var myDataSet3 = new MyDataSet(new List<int>(new int[] { 3,2,1 }));
Console.WriteLine(myDataSet3.GetHashCode());
Console.ReadLine();
}
}
}
显然,这是一个微不足道的实现,但是考虑到已指定的问题的简单性,也许这就足够了?
CREATE TABLE T (Col1 INT, Col2 INT);
GO
INSERT INTO [dbo].[T]([Col1],[Col2])
VALUES (1,1), (1,2), (1,3), (2,1), (2,3), (3,3), (3,1), (3,2), (2,3),(2,1);
GO
SELECT
T1.Col1,
(
SELECT Convert (VARCHAR,Col2) + ','
FROM T T2
WHERE T2.Col1 = T1.Col1
ORDER BY Col2
FOR XML PATH('')
) AS Col2_Cat
INTO X
FROM T T1
GROUP BY Col1 ;
SELECT T.Col1, T.Col2, Y.Col3
FROM T
INNER JOIN
(
SELECT X1.Col1, Min (X2.Col1) AS Col3 FROM X X1
----inner join X X2 on HASHBYTES ('SHA1',X1.Col2_Cat) = HASHBYTES('SHA1',X2.Col2_Cat)
inner join X X2 on X1.Col2_Cat = X2.Col2_Cat
GROUP BY X1.Col1
) AS Y
ON T.Col1 = Y.Col1;
DROP TABLE X
DROP TABLE T