2017-01-05 3 views
1

をランダムな値を選択: - はは、私は、テーブル内のデータを以下している個別の値に基づいて、列から

| item | rate | 
------------------- 
| a  | 50 | 
| a  | 12 | 
| a  | 26 | 
| b  | 12 | 
| b  | 15 | 
| b  | 45 | 
| b  | 10 | 
| c  | 5 | 
| c  | 15 | 

と私は次の出力を返すクエリが必要です。item_noは別個のものでなければならない。すなわち

| item no | rate | 
------------------ 
| a  | 12 | --from (26 , 12 , 50) 
| b  | 45 | --from (12 ,15 , 45 , 10) 
| c  | 5 | --from (5 , 15) 

をし、

ありがとうございます。

答えて

2
WITH 
CTE 
AS 
(
    SELECT DISTINCT 
     item 
    FROM T 
) 
SELECT 
    CTE.item 
    ,A.rate 
FROM 
    CTE 
    CROSS APPLY 
    (
     SELECT TOP(1) 
      T.rate 
     FROM T 
     WHERE T.item = CTE.item 
     ORDER BY CRYPT_GEN_RANDOM(4) 
    ) AS A 
; 

インデックスが役立つだろう。

+0

ありがとう、@ウラジミール、あなたのクエリは3倍速く、他の結果を提供します。 あなたのすべてのお返事ありがとうございます。 – speedyraz

+0

@speedyraz、私はあなたが私の答えを見つけてうれしいです。このアプローチと 'row_number 'の相対的なパフォーマンスは、データの分布(アイテムごとにいくつのレートがあるか)と使用可能なインデックスによって決まります。 –

4

1つの方法は、rウィンドウの機能はitemとなります。次に、各パーティション内でORDER BY NEWID()を使用して、ランダムな順序付けを生成し、各itemパーティションの最初の行を任意に保持します。 (item) include (rate)

SELECT t.item, 
     t.rate 
FROM 
(
    SELECT item, 
      rate, 
      ROW_NUMBER() OVER(PARTITION BY item ORDER BY NEWID()) AS rn 
    FROM yourTable 
) t 
WHERE t.rn = 1 
3

ここでNEWID()は、パーティション内でランダムな順序付けを生成するために使用されます。
パーティション内には、各アイテムの最初の行が保持されます。

with cte as 
    (

     SELECT item, 
       rate, 
       ROW_NUMBER() OVER(PARTITION BY item ORDER BY NEWID()) AS rn 
     FROM #Table1 
     ) 
     select item,rate from cte where rn=1 
+0

これは、OPと将来の読者にとって、答えがより役立つように、いくつかの文脈/説明にコードを含める方が良いでしょう。 – EJoshuaS

1
; WITH tb(item, rate)AS(
    SELECT 'a',50 UNION 
    SELECT 'a',12 UNION 
    SELECT 'a', 26 UNION 
    SELECT 'b',12 UNION 
    SELECT 'b', 15 UNION 
    SELECT 'b',10 UNION 
    SELECT 'c',5 UNION 
    SELECT 'c',15 
    ) 
    SELECT * FROM (
     SELECT *,ROW_NUMBER()OVER(PARTITION BY item ORDER BY NEWID()) AS rn FROM tb 
    ) t WHERE t.rn=1 
2

一度この文字列で検索してください。

select * into #temp from (
     SELECT 'a' item,50 rate 
     UNION ALL 
     SELECT 'a',12 
     UNION ALL 
     SELECT 'a', 26 
     UNION ALL 
     SELECT 'b',12 
     UNION ALL 
     SELECT 'b', 15 
     UNION ALL 
     SELECT 'b',10 
     UNION ALL 
     SELECT 'c',5 
     UNION ALL 
     SELECT 'c',15)as a 

    select * from (
    select *,row_number()over(partition by item ORDER BY newid())as runm from #temp 
    ) as a 
    where runm=1 

注:上記のクエリは、newid()としての新しい出力が実行ごとに新しいIDを生成するたびに表示されます。

関連する問題