2011-03-06 52 views
2

當我在我的表上有多個連接後運行select時,我有2列的輸出,我想爲返回的行集選擇col1和col2的不同組合。在SQL中選擇2列的獨特組合

,我跑將smthing本查詢:

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 

它確定,如果我隨機選擇第二列,因爲我的查詢輸出像是一百萬行,而我真的覺得會有一種情況,即我的Col1和Col2的輸出會相同,即使這種情況下我可以編輯這個值..

你能否幫我一樣..我想基本上col3需要是一個行號我猜,然後我需要選擇兩個cols鹼基隨機行號..我不知道如何transalte這到SQL

考慮的情況1a 1b 1c 1d 1e 2a 2b 2c 2d 2e現在分組將給我所有這些結果,因爲我想1a和2d或1a和2b。任何這樣的組合。

OK讓我解釋一下IM期待什麼:

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) 

現在我不知道我如何得到ROWNUMBER或隨機正常工作!

在此先感謝。

回答

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 
} 
+0

第二個值不是數字然後?最大不起作用! – 2011-03-06 13:17:16

+0

@Asha - 'Max'對字符串有效。它最後按字母順序給你。你的列是什麼數據類型? – 2011-03-06 13:19:19

+0

是。我知道,最大的作品,但然後1 a 1 b 1 z和2 a 2 b 2 z將返回1 z和2 z權利 – 2011-03-06 13:22:20

0

必須使用group by條款:

select a.Col1,b.Col2 
from a 
inner join b on b.Col4=a.Col3 
group by a.Col1 
+1

您不能選擇col1,col2,只能按col1分組。你需要兩個組 – bjorsig 2011-03-06 13:06:27

+0

這對MySQL工作得很好,儘管不知道tsql。 – krtek 2011-03-06 13:10:04

+0

MySQL是唯一允許通過簡單地返回非確定性結果來指定不完整​​的group by子句的數據庫。請參閱此鏈接以解釋爲什麼使用它是一個糟糕的主意:http://rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html – 2011-03-06 13:16:12

0

如果我理解正確的話,你想爲列1和2的每個組合,可以很容易地通過使用GROUP BY或DISTINCT做一行 例如:

SELECT COL1,COL2

從您加入

GROUP BY COL1,C OL2

+0

我想要col1和col2的獨特組合 – 2011-03-06 13:09:47

+0

我不想讓每個distint組合有一行..考慮1a 1b 1c 1d 1e 2a 2b 2c 2d 2e現在分組將會給我所有這些結果,因爲我想要1a和2d或1a和2b。任何這樣的組合..第二行可以隨機選擇 – 2011-03-06 13:10:52

+0

如果你運行查詢,你會得到col1和col2中每個組合的確切的一行,這不是愚蠢的,它是SQL 101.是不是你想要的@阿莎? – bjorsig 2011-03-06 13:12:00

3

你需要按​​僅​​得到不同的,那麼因爲b.Col2不包括在該組中,你需要找到一個合適的聚合函數,以減少該組中的所有值只是一個,MIN是不夠好如果你只是想要其中的一個值。

select a.Col1, MIN(b.Col2) as c2 
from a 
inner join b on b.Col4=a.Col3 
group by a.Col1 
+0

第二個值是那麼不是一個數字?最大不起作用! – 2011-03-06 13:17:41

+0

@Asha:[MSDN:MAX](http://msdn.microsoft.com/en-us/library/ms187751.aspx):「MAX可以與數字,字符和日期時間列一起使用,但不能與位列一起使用。不允許使用聚合函數和子查詢。「 – 2011-03-06 13:20:47

+0

是。我知道,最大的作品,但然後1 a 1 b 1 z和2 a 2 b 2 z將返回1 z和2 z右 – 2011-03-06 13:22:41