1

我有一个问题,我将尝试解释。我的想法是在 C# 中的 SSIS 中创建一个脚本,并为表中每个唯一的 ID 组合生成一个 ID 列表。

我有一个包含两列的 SQL 服务器表。这些列是 ID(我可以将它们设为数字,但在原始格式中它们是字母数字字符串)。我想从连接到第 1 列的第 2 列中的一组 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 声望”来发布图片,所以我希望我的插图能解释这个问题......

4

2 回答 2

0

作为尝试理解您的问题的进一步示例,您是否希望 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

ETC

如果是这样,那么根据上述假设并回答您的问题:

  • 是的,哈希函数可以做到
  • 如何为第 1 组和第 3 组(在您的示例中)获得相同的“生成的 ID”将取决于您的 GetHashCode() 覆盖/实施
  • 是的,您可能需要排序,但同样,这取决于您的实现。

由于您指的是在 SSIS 中使用 C# 脚本,因此可能的 C# 实现可能是实现一个(非常!)简单的 Hash 类,它给出了一组 Col2 值(对于每个数据集),简单地说:

  1. 对 Col2 的值进行排序,以使它们以“正确”的顺序排列,并且
  2. 返回已排序数据集的整数表示以获取哈希(例如,将 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();
        }
    }
}

显然这是一个微不足道的实现,但是考虑到问题的简单性,因为它已经指定,也许这就足够了?

于 2013-10-29T12:44:10.917 回答
0
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
于 2013-10-29T15:18:04.103 回答