SQL Server中的随机连接具有不同数量的随机结果

时间:2017-07-19 21:45:01

标签: random sql-server-2012 top-n

SQL Server的SQL变得如此聪明,以至于看起来可能需要程序解决方案的SQL通常可以使用纯SQL来完成。我想知道这是否是其中一次 假设我们有一个STATES表和一个CITIES表。

STATES:
State:  NY

CITIES
State: NY
City:  Armonk

现在让我们用第三个表复杂化:INSTRUCTIONS

INSTRUCTIONS
State: NY
HowMany: 17

State: NJ
HowMany: 11

当三个表在State上连接时,SQL Server SQL中是否有任何方法可以从CITIES表中随机选择HowMany个城市?

我们事先并不知道“前N”。它按州改变。

当然,州表将包含所有50个州,每个州的所有城市都有城市表,而且每个州的指令将有一个记录,确定需要多少个城市(随机选择)。 / p>

P.S。样本期望的结果(假设NY的指令是HowMany = 5,NJ的指令是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

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

我发现其他答案中使用的RAND()函数会因为不是每行的新随机数而导致一些问题。

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

答案 2 :(得分:0)

使用不使用DDL(数据定义语言)的查询

,然后另一个答案
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