名字应该随机与其他名字匹配



所有的名字应该随机匹配,当我试图再次运行查询时,名字应该与他人的名字匹配。不匹配FIRST time match

例如,我在一个表中有6条记录…

名字列看起来像:

JHON
LEE
SAM
HARRY
JIM
KRUK

所以我想要像

这样的结果
First name1 First name2
Jhon.       Harry
LEE.        KRUK
HARRY       SAM

最简单的解决方案是首先对记录进行随机排序,然后计算分组和组内的序列号,最后选择出组作为行。

您可以按照下面的逻辑操作:https://dbfiddle.uk/9JlK59w4

DECLARE @Sorted TABLE
(
Id INT PRIMARY KEY,
FirstName varchar(30),
RowNum INT IDENTITY(1,1) 
);
INSERT INTO @Sorted (Id, FirstName)
SELECT Id, FirstName
FROM People 
ORDER BY NEWID();

WITH Pairs as
(
SELECT * 
, (RowNum+1)/2 as PairNum
, RowNum % 2 as Ordinal
FROM @Sorted 
)
SELECT 
Person1.FirstName as [First name1], Person2.FirstName as [First name2]
FROM Pairs Person1
LEFT JOIN Pairs Person2 ON Person1.PairNum = Person2.PairNum AND Person2.Ordinal = 1
WHERE Person1.Ordinal = 0
ORDER BY Person1.PairNum
这里使用
  • ORDER BY NEWID()对记录进行随机排序。注意,它是不确定的,每次执行都会返回一个新值。虽然效率不高,但符合我们的要求。

    您不能轻易地使用CTE生成随机排序记录的列表,因为CTE的结果是而不是缓存。每次在后续逻辑中引用CTE时,都会导致对表达式重新求值。运行这个工具几次,看看它是如何不正确地分配名称的:https://dbfiddle.uk/rpPdkkAG

    由于NEWID()的波动性,本例将结果存储在表值变量中。对于非常大的记录列表,临时表可能更有效。

  • PairNum使用简单的除以n逻辑分配长度为n

    的群号。
    • 有必要将1添加到RowNum,因为整数数学将四舍五入,在小提琴中看到这一点。
  • Ordinal使用RowNumber上的模,是一个值,我们可以用它来区分Person 1Person 2。这有助于我们保持逻辑的其余部分是确定的。

在最终的SELECT中,我们首先从Pairs中选择具有0Ordinal,然后我们加入具有1OrdinalPairNum匹配的Pairs


您可以看到,我添加了一个使用3个组的解决方案,以展示如何轻松地扩展到更大的组。

相关内容

  • 没有找到相关文章

最新更新