2017-07-03 6 views
0

結果が返されない場合は、クエリを繰り返す方法についてアドバイスしてください。私はRANDを使用してDBからランダムな人物を生成しようとしていますが、その番号が以前に使用されていない(その情報は "allready_drawn"という列に格納されている) 2番目の条件"is null"のために、クエリが前に描画された番号を超えたとき、結果は表示されません。 数字を思いつくまで、私は再度クエリを再実行する必要があります。結果が返ってこない場合は、クエリを繰り返してください。

DECLARE @min INTEGER; 
DECLARE @max INTEGER; 

set @min = (select top 1 id from [dbo].[persons] where sector = 8 order by id ASC); 
set @max = (select top 1 id from [dbo].[persons] where sector = 8 order by id DESC); 

select 
ordial, 
name_surname 

from [dbo].[persons] 

where id = ROUND(((@max - @min) * RAND() + @min), 0) and allready_drawn is NULL 

結果(2つの可能な結果):

enter image description here

任意の提案が高く評価され、私は事前にみんなに感謝したいと思います。

+0

最終的なクエリではなく、 '@ min'と' @max'に対してなぜ 'sector'を制限しますか? –

+0

@GordonLinoff - 良い質問私の友人:)それは私が他のものに集中していたので、私から離れましたので、そこにそれを追加することについても忘れてしまいました.../ –

答えて

0

たら、それを実行する必要がありますので、単に「ID」フィルタを削除するには、このを試してみてください。密なキーを持つ非常に大きなテーブルの場合、マッチを見つけるまで、minとmaxの間でキー値をランダムに選択して再ピッキングすることも公正であり、テーブル全体をソートするよりも安価です。

また、元の投稿にはバグがあります。最小と最大の行は、それぞれがより小さい間隔にマップされるので、他のものと比べて半分だけ頻繁に選択されるためです。修正するには、乱数を@minから@max + 1に生成し、丸めるのではなく切り捨てます。このようにしてN [N、N + 1]の間隔をNにマッピングします。

この選択方法では、一致するものが見つかるまで繰り返します。

--drop table persons 
go 
create table persons(id int, ordial int, name_surname varchar(2000), sector int, allready_drawn bit) 

insert into persons(id,ordial,name_surname,sector, allready_drawn) 
      values (1,1,'foo',8,null),(2,2,'foo2',8,null),(100,100,'foo100',8,null) 

go 
declare @min int = (select top 1 id from [dbo].[persons] where sector = 8 order by id ASC); 
declare @max int = 1+ (select top 1 id from [dbo].[persons] where sector = 8 order by id DESC); 


set nocount on 
declare @results table(ordial int, name_surname varchar(2000)) 

declare @i int = 0 
declare @selected bit = 0 


while @selected = 0 
begin 
    set @i += 1 

    insert into @results(ordial,name_surname) 
    select 
    ordial, 
    name_surname 
    from [dbo].[persons] 
    where id = ROUND(((@max - @min) * RAND() + @min), 0, 1) and allready_drawn is NULL 

    if @@ROWCOUNT > 0 
    begin 
     select *, @i tries from @results 
     set @selected = 1 
    end 
end 
+0

マインド=吹き。ブラウン帽子の下の帽子:)私はこのスポット・オンの例から多くを学んだ!あなたの時間と貢献に感謝します。 –

1

あなただけそれが正解だが、それはそれはあまりにも高価ですが可能です@gbn

select TOP 1 
    ordial, 
    name_surname 
from [dbo].[persons] 
where allready_drawn is NULL 
ORDER BY NEWID() 
+0

初めてNEWID - しかし、私が望むようにクエリを磨くことができなかった...投稿したソリューションは非常に創造的な、私は言わなければならない!私は巨大なソーステーブル(少し高価)のため今回は使用しませんでしたが、将来のいくつかのプロジェクトではこの宝石をクエリ宝箱に保存しました。あなたの貢献に感謝します。 –

関連する問題