2

テーブルで多数の結合を行った後に選択を実行すると、2 列の出力が得られ、返される行セットに対して col1 と col2 の個別の組み合わせを選択したいと考えています。

私が実行するクエリは次のようになります。

select a.Col1,b.Col2 from a inner join b on b.Col4=a.Col3

出力は次のようになります

Col1 Col2  
1   z  
2   z  
2   x  
2   y  
3   x  
3   x  
3   y  
4   a  
4   b  
5   b  
5   b  
6   c  
6   c  
6   d  

今、私は出力が次のようなものであることを望みます

1  z  
2  y  
3  x  
4  a  
5  b  
6  d 

クエリ出力が100万行のようにランダムに2番目の列を選択しても問題ありません。値を編集できる場合でも、Col1とCol2の出力が同じになる場合があるとは本当に思いません..

同じことを手伝ってもらえますか..基本的に、col3は行番号である必要があると思います.次に、ランダムな行番号に基づいて2つの列ベースを選択する必要があります..これをSQLに変換する方法がわかりません

ケース1a 1b 1c 1d 1e 2a 2b 2c 2d 2eを考えてみましょう。グループ化すると、1aと2dまたは1aと2bが必要な場合にこれらすべての結果が得られます。そのような任意の組み合わせ。

OK、私が期待していることを説明させてください:

with rs as(
select a.Col1,b.Col2,rownumber() as rowNumber from a inner join b on b.Col4=a.Col3)
select rs.Col1,rs.Col2 from rs where rs.rowNumber=Round( Rand() *100)

今、行番号またはランダムを正しく機能させる方法がわかりません!!

前もって感謝します。

4

4 に答える 4

6

col2返される値が気にならない場合

select a.Col1,MAX(b.Col2) AS Col2
from a inner join b on b.Col4=a.Col3 
GROUP BY a.Col1

ランダムな値が必要な場合は、以下のアプローチを使用できます。

 ;WITH T
     AS (SELECT a.Col1,
                b.Col2
                ROW_NUMBER() OVER (PARTITION BY a.Col1 ORDER BY (SELECT NEWID())
                ) AS RN
         FROM   a
                INNER JOIN b
                  ON b.Col4 = a.Col3)
SELECT Col1,
       Col2
FROM   T
WHERE  RN = 1  

または、代わりに CLR 集計関数を使用します。partition, newid()このアプローチには、以下の実装例でソートする必要がないという利点があります。

using System;
using System.Data.SqlTypes;
using System.IO;
using System.Security.Cryptography;
using Microsoft.SqlServer.Server;

[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000)]
public struct Random : IBinarySerialize
{
    private MaxSoFar _maxSoFar;

    public void Init()
    {
    }

    public void Accumulate(SqlString value)
    {
        int rnd = GetRandom();
        if (!_maxSoFar.Initialised || (rnd > _maxSoFar.Rand))
            _maxSoFar = new MaxSoFar(value, rnd) {Rand = rnd, Value = value};
    }

    public void Merge(Random group)
    {
        if (_maxSoFar.Rand > group._maxSoFar.Rand)
        {
            _maxSoFar = group._maxSoFar;
        }
    }

    private static int GetRandom()
    {
        var buffer = new byte[4];

        new RNGCryptoServiceProvider().GetBytes(buffer);
        return BitConverter.ToInt32(buffer, 0);
    }

    public SqlString Terminate()
    {
        return _maxSoFar.Value;
    }

    #region Nested type: MaxSoFar

    private struct MaxSoFar
    {
        private SqlString _value;

        public MaxSoFar(SqlString value, int rand) : this()
        {
            Value = value;
            Rand = rand;
            Initialised = true;
        }

        public SqlString Value
        {
            get { return _value; }
            set
            {
                _value = value;
                IsNull = value.IsNull;
            }
        }

        public int Rand { get; set; }

        public bool Initialised { get; set; }
        public bool IsNull { get; set; }
    }

    #endregion


    #region IBinarySerialize Members

    public void Read(BinaryReader r)
    {
        _maxSoFar.Rand = r.ReadInt32();
        _maxSoFar.Initialised = r.ReadBoolean();
        _maxSoFar.IsNull = r.ReadBoolean();

        if (_maxSoFar.Initialised && !_maxSoFar.IsNull)
            _maxSoFar.Value = r.ReadString();
    }

    public void Write(BinaryWriter w)
    {
        w.Write(_maxSoFar.Rand);
        w.Write(_maxSoFar.Initialised);
        w.Write(_maxSoFar.IsNull);

        if (!_maxSoFar.IsNull)
            w.Write(_maxSoFar.Value.Value);
    }

    #endregion
}
于 2011-03-06T13:16:21.837 に答える
3

のみでa.Col1区別するには、グループ化する必要があります。グループに含まれていないため、グループ内のすべての値を 1 つに減らす適切な集計関数を見つける必要があります。値の 1 つだけが必要な場合は、これで十分です。a.Col1b.Col2MIN

select a.Col1, MIN(b.Col2) as c2
from a 
inner join b on b.Col4=a.Col3
group by a.Col1
于 2011-03-06T13:15:01.697 に答える
0

group by次の句を使用する必要があります。

select a.Col1,b.Col2 
from a 
inner join b on b.Col4=a.Col3
group by a.Col1
于 2011-03-06T13:04:14.683 に答える
0

私の理解が正しければ、列 1 と列 2 の組み合わせごとに 1 つの行が必要です。これは、たとえば GROUP BY または DISTINCT を使用して簡単に行うことができます。

SELECT 列 1、列 2

あなたの仲間から

GROUP BY col1、col2

于 2011-03-06T13:05:33.937 に答える