如何在 TSQL 中将一个表中的行均匀分布到另一个表中的行?

Sli*_*345 4 t-sql sql-server algorithm join

我试图找出一个 SQL 查询,它将记录从一个表均匀地分配或分配到另一个表。解释它的最好方法是通过一个人为的例子。

假设我有一个员工表,我想从颜色表中为每个人分配一种颜色。

我想确保颜色均匀分布,但员工没有属性可以预测他们会收到哪种颜色。

雇员:

Sam
John
Jack
April
Sonny
Jill
Jane
Run Code Online (Sandbox Code Playgroud)

颜色:

Red
Green
Blue
Run Code Online (Sandbox Code Playgroud)

结果:

Sam - Red
John - Green
Jack - Blue
April - Red
Sonny - Green
Jill - Blue
Jane - Red
Run Code Online (Sandbox Code Playgroud)

如何在 TSQL 中构造此连接?

Chr*_*ian 5

我知道问题是关于 SQLServer 的,但是对于那些对不使用 NTILE 且仅使用 row_number 的解决方案感兴趣的人:

-- (PostgreSQL syntax, but can be easly adapted to any DB)

with 

-- "uses" a dummy colors table just for testing
colors as 
  (select 'Red' as color union all
   select 'Green'        union all
   select 'Blue' 
  )
,

-- "uses" a dummy employees table just for testing
employees as 
  (select 'John' as employee union all
   select 'Jack'             union all
   select 'April'            union all
   select 'Sonny'            union all
   select 'Jill'             union all
   select 'Jane'             
  )
,

-- here's the trick: 

-- first we define a code_num as row_number for each color
c as
(select *, 
        row_number() over() as color_num 
   from colors
),

-- and then we define a code_num for each employee as 
-- ((row_number-1) "mod" (colors' table count)) +1
e as 
(select *, 
        (((row_number() over())-1) % (select count(*) from colors))+1 as color_num 
   from employees
)

-- get both tables joined by color_num   
select e.employee, 
       c.color
  from e 
  join c on c.color_num = e.color_num
Run Code Online (Sandbox Code Playgroud)

输出:

employee  color
---------------
    John    Red
    Jack  Green
   April   Blue
   Sonny    Red
    Jill  Green
    Jane   Blue
Run Code Online (Sandbox Code Playgroud)