SQL - 在 X 个表中平均分配相同的值
SQL - Distribute Same Values equally across X number of tables
我想看看是否有人知道在 "x" 个临时 table 中均匀分布多个相似值的方法,确保 'like' 值(此团队名称相同例如)永远不要被归为一个特定的 table。我想做的是为一场比赛制造热度,并在 table 之间平均分配队伍。例如:
**Teams**
-----------
Los Angeles
New York
New York
Los Angeles
Florida
Florida
Arizona
Texas
Alabama
Alaska
New York
New York
New York
我希望分配最终是这样的,所有多支球队平均分配到 2(或 3 或 4)场比赛中:
**Heat One**
-------------
Los Angeles
New York
Florida
Arizona
Alabama
New York
New York
**Heat Two**
------------
Los Angeles
New York
Florida
Texas
Alaska
New York
这种方法听起来不对(有单独的表称为 Heat1、Heat2 等)所以您可能想重新考虑您在做什么,但如果您的情况决定这是一个好方法,那么如何分配每个团队的随机唯一(但连续)编号然后使用 MOD 将团队分开进行?为了让 'like' 队(相同的队名)进入不同的预赛,他们只需要随机在一起,MOD 将他们分开。
create table dbo.Teams (TeamId int, TeamName varchar(32))
go
insert dbo.Teams values
( 1, 'Los Angeles'),
( 2, 'New York'),
( 3, 'New York'),
( 4, 'Los Angeles'),
( 5, 'Florida'),
( 6, 'Florida'),
( 7, 'Arizona'),
( 8, 'Texas'),
( 9, 'Alabama'),
(10, 'Alaska'),
(11, 'New York'),
(12, 'New York'),
(13, 'New York')
go
-- First get a random number per unique team name
; with cte as (
select row_number() over (order by newid()) as lrn, t.TeamName
from dbo.Teams t
group by t.TeamName
)
-- Second get a unique random number per team with like teams ordered together
select row_number() over (order by lrn, newid()) - 1 as rn, t.*
into #teams
from dbo.Teams t
join cte c on c.TeamName = t.TeamName
select 'Heat1', *
from #teams
where rn % 4 = 0
select 'Heat2', *
from #teams
where rn % 4 = 1
select 'Heat3', *
from #teams
where rn % 4 = 2
select 'Heat4', *
from #teams
where rn % 4 = 3
从 SQL Server 2005 开始,有一个用于存储数据的本机功能。 NTILE()
NTILE 函数是 SQL Server 2005 中引入的四个 windowing 函数中的第四个。NTILE 采用不同的方法对数据进行分区。 ROW_NUMBER、RANK 和 DENSE_RANK 将根据分区键生成可变大小的数据桶。 NTILE 尝试将数据分成相等的、固定大小的桶。 BOL 有一个综合页面比较排名功能,如果
你想要一个关于它们效果的快速视觉参考。
语法
NTILE 的语法与其他 window 函数略有不同。它是 NTILE(@BUCKET_COUNT) OVER ([PARTITION BY _] ORDER BY _)
,其中 @BUCKET_COUNT 是正整数或 bigint 值。
挑战在于确保我们获得良好的分布,这是受随机数生成器模糊影响的部分(newid 调用/(SELECT NULL))。
利用 Rhys 的设置
CREATE table dbo.Teams (TeamId int, TeamName varchar(32));
insert dbo.Teams values
( 1, 'Los Angeles'),
( 2, 'New York'),
( 3, 'New York'),
( 4, 'Los Angeles'),
( 5, 'Florida'),
( 6, 'Florida'),
( 7, 'Arizona'),
( 8, 'Texas'),
( 9, 'Alabama'),
(10, 'Alaska'),
(11, 'New York'),
(12, 'New York'),
(13, 'New York');
SELECT
NTILE(2) OVER (ORDER BY NEWID()) AS Heat
, NTILE(2) OVER (ORDER BY (SELECT NULL)) AS HeatAlternate
, T.TeamName
, T.TeamId
FROM
dbo.Teams AS T
ORDER BY
1,3;
这种方法的一个好处是,它可以通过简单地更改传递给 ntile 的值来切换成您想要的任何分桶大小。它还应该更好地扩展,因为它只需要一次通过源 table.
我想看看是否有人知道在 "x" 个临时 table 中均匀分布多个相似值的方法,确保 'like' 值(此团队名称相同例如)永远不要被归为一个特定的 table。我想做的是为一场比赛制造热度,并在 table 之间平均分配队伍。例如:
**Teams**
-----------
Los Angeles
New York
New York
Los Angeles
Florida
Florida
Arizona
Texas
Alabama
Alaska
New York
New York
New York
我希望分配最终是这样的,所有多支球队平均分配到 2(或 3 或 4)场比赛中:
**Heat One**
-------------
Los Angeles
New York
Florida
Arizona
Alabama
New York
New York
**Heat Two**
------------
Los Angeles
New York
Florida
Texas
Alaska
New York
这种方法听起来不对(有单独的表称为 Heat1、Heat2 等)所以您可能想重新考虑您在做什么,但如果您的情况决定这是一个好方法,那么如何分配每个团队的随机唯一(但连续)编号然后使用 MOD 将团队分开进行?为了让 'like' 队(相同的队名)进入不同的预赛,他们只需要随机在一起,MOD 将他们分开。
create table dbo.Teams (TeamId int, TeamName varchar(32))
go
insert dbo.Teams values
( 1, 'Los Angeles'),
( 2, 'New York'),
( 3, 'New York'),
( 4, 'Los Angeles'),
( 5, 'Florida'),
( 6, 'Florida'),
( 7, 'Arizona'),
( 8, 'Texas'),
( 9, 'Alabama'),
(10, 'Alaska'),
(11, 'New York'),
(12, 'New York'),
(13, 'New York')
go
-- First get a random number per unique team name
; with cte as (
select row_number() over (order by newid()) as lrn, t.TeamName
from dbo.Teams t
group by t.TeamName
)
-- Second get a unique random number per team with like teams ordered together
select row_number() over (order by lrn, newid()) - 1 as rn, t.*
into #teams
from dbo.Teams t
join cte c on c.TeamName = t.TeamName
select 'Heat1', *
from #teams
where rn % 4 = 0
select 'Heat2', *
from #teams
where rn % 4 = 1
select 'Heat3', *
from #teams
where rn % 4 = 2
select 'Heat4', *
from #teams
where rn % 4 = 3
从 SQL Server 2005 开始,有一个用于存储数据的本机功能。 NTILE()
NTILE 函数是 SQL Server 2005 中引入的四个 windowing 函数中的第四个。NTILE 采用不同的方法对数据进行分区。 ROW_NUMBER、RANK 和 DENSE_RANK 将根据分区键生成可变大小的数据桶。 NTILE 尝试将数据分成相等的、固定大小的桶。 BOL 有一个综合页面比较排名功能,如果 你想要一个关于它们效果的快速视觉参考。
语法
NTILE 的语法与其他 window 函数略有不同。它是 NTILE(@BUCKET_COUNT) OVER ([PARTITION BY _] ORDER BY _)
,其中 @BUCKET_COUNT 是正整数或 bigint 值。
挑战在于确保我们获得良好的分布,这是受随机数生成器模糊影响的部分(newid 调用/(SELECT NULL))。
利用 Rhys 的设置
CREATE table dbo.Teams (TeamId int, TeamName varchar(32));
insert dbo.Teams values
( 1, 'Los Angeles'),
( 2, 'New York'),
( 3, 'New York'),
( 4, 'Los Angeles'),
( 5, 'Florida'),
( 6, 'Florida'),
( 7, 'Arizona'),
( 8, 'Texas'),
( 9, 'Alabama'),
(10, 'Alaska'),
(11, 'New York'),
(12, 'New York'),
(13, 'New York');
SELECT
NTILE(2) OVER (ORDER BY NEWID()) AS Heat
, NTILE(2) OVER (ORDER BY (SELECT NULL)) AS HeatAlternate
, T.TeamName
, T.TeamId
FROM
dbo.Teams AS T
ORDER BY
1,3;
这种方法的一个好处是,它可以通过简单地更改传递给 ntile 的值来切换成您想要的任何分桶大小。它还应该更好地扩展,因为它只需要一次通过源 table.