1

説明しようとする問題があります。私の考えは、C# の SSIS でスクリプトを作成し、それを使用して、テーブル内の ID の一意の組み合わせごとに ID のリストを生成することです。

2 つの列で構成される 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
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 に答える
0

問題を理解するためのさらなる例として、Col2 の次の値のセットが、以下にリストされているすべてのケースの「生成された ID」値として「123」のような値を返すことを期待しますか?

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# 実装は、(データ セットごとに) Col2 値のセットを指定する (非常に!) 単純な Hash クラスを実装することです。

  1. Col2 の値をソートして「正しい」順序で取得し、
  2. ハッシュを取得するために、ソートされたデータセットの整数表現を返します (たとえば、int を文字列として連結し、次に int に変換します)。

ハッシュ クラスは、(ベース?) クラスの GetHashCode() 関数でインスタンス化できます。この関数は、Col2 値を渡され、上記の手順 (1) と (2) を実行し、必要に応じてハッシュ コードを返します。

次のようなものがうまくいくかもしれません (使用している .NET バージョンで Generics にアクセスできると仮定します):

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 に答える