2017-07-19 16 views
0

SQL ServerのSQLは非常に巧妙になっているため、純粋なSQLで手続き型の解決策が必要な場合があります。これがその時代かどうか疑問に思っています。
STATESテーブルとCITIESテーブルがあるとします。ランダムな結果のさまざまな数でSQL Serverのランダム結合

STATES: 
State: NY 

CITIES 
State: NY 
City: Armonk 

今度は、3番目の表で物事を複雑にしてみましょう:取扱説明書

INSTRUCTIONS 
State: NY 
HowMany: 17 

State: NJ 
HowMany: 11 

3つの表は、国家に接合する際CITIESテーブルからランダムにHowMany都市を選択するためのSQL ServerのSQLのいずれかの方法はあります?

「トップN」は事前にわかりません。それは州によって変わります。

もちろん、状態テーブルには50州すべてがあり、都市ごとに各都市のすべての都市があり、命令は州ごとに1つのレコードを持ち、その州からいくつの都市が必要なのかをランダムに選択します。

P.S.試料所望の結果(NY指示を想定するhowManyが= 5であり、ニュージャージー州の指示がhowManyが= 4、及びorder by STATES.stateである):次いで

NJ.....Princeton 
NJ.....Newark 
NJ.....Camden 
NJ.....Princeton 
NY.....Armonk 
NY.....Schenectady 
NY.....White Plains 
NY.....Niagara Falls 
NY.....Rochester 
+1

あなたがサンプル望ましい結果を投稿できますか? –

+0

"命令には状態ごとに1レコードがあります" なぜ2つのテーブルを使用するのですか? HowManyはINSTRUCTIONSからSTATESテーブルに移動できました。 –

+0

@Kjetil S.同意しましたが、この時点でリファクタリングする必要はありません。 – Tim

答えて

1

は、新たな乱数されていないことにより、いくつかの問題が発生します各行について。

CHECKSUM(NEWID())はこのシナリオではうまくいきました。

RAND not different for every row in T-SQL UPDATEを参照してください)私は、このソリューションは素晴らしく、整頓だと思う:

SELECT 
RandomCities.[State] 
,[RandomCities].City 
FROM 
    (
     SELECT 
     s.[state] 
     ,city 
     ,ROW_NUMBER() OVER (PARTITION BY s.[State] ORDER BY CHECKSUM(NEWID())) AS [RandomOrder] 
     FROM 
     States s 
     INNER JOIN Cities c ON c.[state]=s.[state] 
    ) AS RandomCities 
INNER JOIN instructions i ON i.[state]=RandomCities.[state] 
WHERE RandomCities.RandomOrder<=i.HowMany 
+1

ニースはきちんと整理されています。 – Tim

1
with 
    states as (
    select 'NY' state union 
    select 'NJ' state 
), 
    instructions as (
    select 'NY' state, 2 howmany union 
    select 'NJ' state, 3 howmany 
), 
    cities as (
    select 'NJ' state,'Princeton' city union 
    select 'NJ' state,'Newark' city union 
    select 'NJ' state,'Camden' city union 
    select 'NJ' state,'Hamilton' city union 
    select 'NY' state,'Armonk' city union 
    select 'NY' state,'Schenectady' city union 
    select 'NY' state,'White Plains' city union 
    select 'NY' state,'Niagara Falls' city union 
    select 'NY' state,'Rochester' city 
), 
    cities_rnd as (
    select c.*,rand() rnd from cities c 
), 
    cities_ranked as (
    select c.*, dense_rank() over (partition by c.state order by c.rnd) rank from cities_rnd c 
) 
select c.*,i.howmany 
from cities_ranked c 
join instructions i on i.state=c.state 
join states  s on s.state=c.state --needless line 
where c.rank <= i.howmany; 
+0

エラー: 'TOP、OFFSETまたはFOR XMLも指定されていない限り、ビュー、インライン関数、派生テーブル、サブクエリ、および共通テーブル式ではORDER BY句が無効です。 ' – Tim

+0

これを修正しました –

0

異なる他の回答DDLを使用していないクエリを使用して(データ定義言語)私は他の回答に使用されるRAND()関数を見つける

SET @row_num2= 0; 
SELECT *,@row_num2 := @row_num2+1 as rownum2 FROM (SELECT States.State,Cities.City,Instructions.HowMany 
from States,Cities, Instructions 
WHERE States.State = Cities.State and States.State = Instructions.State 
ORDER BY RAND()) as t HAVING rownum2 >= t.HowMany 

http://sqlfiddle.com/#!9/b96d3b/37

関連する問題