2013-07-02 3 views
5

私はMicrosoftのSQL Server 2008を使用しています。ランダムに1つの値を取得するために外部キーを集計する必要がありますが、私は困惑しています。以下の表を考慮する:ランダムに集計しますか?

id   fk   val 
----------- ----------- ---- 
1   100   abc 
2   101   def 
3   102   ghi 
4   102   jkl 

所望の結果は次のようになります。FK 102用valがランダムになり

fk   val 
----------- ---- 
100   abc 
101   def 
102   ghi 

いずれかの "GHI" 又は "JKL"。

NEWID()を使用して一意のランダム値を取得しようとしましたが、サブクエリによってNEWID()値が異なるため、JOINは失敗します。

WITH withTable AS (
    SELECT id, fk, val, CAST(NEWID() AS CHAR(36)) random 
    FROM exampleTable 
) 
SELECT t1.fk, t1.val 
FROM withTable t1 
JOIN (
    SELECT fk, MAX(random) random 
    FROM withTable 
    GROUP BY fk 
) t2 ON t2.random = t1.random 
; 

私は困惑しています。どんなアイデアでも大歓迎です。

+1

@ypercube:ポストの最初の文で言及されました... –

答えて

6

ROW_NUMBER()と呼ばれる特別なランキング機能を使用して少し違って考えるかもしれません。

基本的には、fkでグループ化され、1から始まり、ソート値としてNEWID()関数を使用してランダムに並べ替えられた数値を各行に適用します。このことから、あなたは、行番号は、この技術の効果は、それはそれはの世話をするという点で、このアプローチは、追加の利点を持っている価値1.

WITH withTable(id, fk, val, rownum) AS 
(
    SELECT 
     id, fk, val, ROW_NUMBER() OVER (PARTITION BY fk ORDER BY NEWID()) 
    FROM 
     exampleTable 
) 
SELECT 
    * 
FROM 
    withTable 
WHERE 
    rownum = 1 

が割り当てられますどの行ランダム化ということである1だったすべての行を選択することができます1回のパスでのグループ化とランダム化。

+0

あなたは私よりも速いですが、私は[SQL FIDDLE EXAMPLE](http://sqlfiddle.com/#!6)を作成しました。/dc46b/7) –

+0

ありがとう、PARTITION BYコマンドについて知らなかった – user1886415

+3

このように 'NEWID'を使用することに注意してください。副作用のある非決定的なスカラ関数であり、直感的ではありません。スカラ関数が何回あるかについての[非常に少ない保証](http://connect.microsoft.com/SQLServer/feedback/details/350485/bug-with-newid-and-table-expressions)(将来について)実行された - またはまったく。ここのコードは、保存されている場合とされていない場合があります。例を見るには、 'ORDER BY NEWID()'を 'ORDER BY(SELECT NEWID())'に変更してください。 –

1

あなたがいない集約ではなくrow_number()でこれを行うことができます。

select id, fk, val 
from (select t1.*, 
      row_number() over (partition by fk order by newid()) as seqnum 
     from withTable t1 
    ) t1 
where seqnum = 1 
0

一つの選択肢は

)NEWID(でTOP 1 ORDERを選択し、一時テーブルに同じFKされた値を取得することです

それはあなたのために働くはずです。

関連する問題