在这个问题中,@GordonLinoff 为我最初的问题提供了一个解决方案(递归公用表表达式)。这是一个后续问题。
最初的问题:
我如何循环注册直到达到一定数量(总和)的 AmountPersons 并且如果下一个 AmountPersons 太高而无法被邀请检查下一行的 AmountPersons 是否合适?
请通过上面的链接检查最初的问题以获取完整的图片。
新情况:
首先,我们有 20 个可用席位,我们遍历数据行来填补这些席位(初始问题)。
然后我对Count_Invitedorder by
进行排序并从row_number()
函数中更新。因此,被邀请最少的人应该获得优先权。
然后我还添加了Count_Registered列,因为注册最多但被邀请最少的人也应该获得优先权。
新问题:
如果第三个、第四个、第五个 .. 用户也具有相同的值(Count_Invited 和 Count_Registered 和 AmountPersons 为 1),我如何从下面的结果中打乱被邀请的最后两个人?
顶部数据的排序正确,但只有最后几行需要随机化被邀请者。
我知道这种ORDER BY NEWID()
随机化行的功能,但在我的情况下它不能应用于所有行。我不知道如何处理这个...更多信息如下。
新的 T-SQL 代码:
WITH tn AS (
SELECT g.[Id],
g.[FirstName],
g.[LastName],
g.[E-mail],
g.[Count_Invited],
g.[Count_Registered],
r.[DateReservation],
r.[AmountPersons],
row_number() over(order by g.[Count_Invited], g.[Count_Registered] DESC) as seqnum
FROM USERTABLE g
INNER JOIN RESERVATION r ON r.[UserId] = g.[Id]
WHERE r.[PartyId] = 21
),
cte AS (
SELECT [Id], [FirstName], [LastName], [E-mail], [Count_Invited], [Count_Registered], [DateReservation],
[AmountPersons], [AmountPersons] as total, 1 as is_included, seqnum
FROM tn
WHERE seqnum = 1
UNION ALL
SELECT tn.[Id], tn.[FirstName], tn.[LastName], tn.[E-mail], tn.[Count_Invited], tn.[Count_Registered], tn.[DateReservation], tn.[AmountPersons],
(case when tn.[AmountPersons] +cte.total <= 20
then tn.[AmountPersons] +cte.total
else cte.total
end),
(case when tn.[AmountPersons] +cte.total <= 20
then 1
else 0
end) as is_included,
tn.seqnum
FROM cte join
tn
on tn.seqnum = cte.seqnum + 1
WHERE cte.total < 20
)
SELECT cte.Id AS userId,
cte.FirstName,
cte.LastName,
cte.[E-mail],
cte.Count_Invited,
cte.Count_Registered,
cte.AmountPersons,
cte.DateReservation
FROM cte
WHERE is_included = 1
我希望这对某人有意义。谢谢你。
编辑:额外的澄清步骤。这是应该发生的:
-- 声明 amountSeats = 25
-- 选择 Count_Invited 的第一个值
-- 如果该值为 0
-- 对 Count_Invited 为 0 的 AmountPersons(多行)求和
-- 如果该总和低于 amountSeats,假设现在是 10
-- 在临时表中插入所有值为 0 的行(不确定这是否是要走的路……)
-- 选择 Count_Invited 的第二个值(不是第二行) --> 所以 Count_Invited 不是 0
-- 如果该值为 1
-- 对 Count_Invited 为 1 的 AmountPersons(多行)求和
-- Count_Invited 的总计数 = 0 + Count_Invited = 1
-- 如果这个总和仍然低于 amountSeats,假设现在是 15
-- 在临时表中插入(添加)Count_Invited 1 的所有行
-- 选择 Count_Invited 的第 3 个值(不是第 3 行) --> 所以 Count_Invited NOT IN (0, 1)
-- 如果该值为 5
-- 计数 AmountPersons(多行),其中 Count_Invited 为 5
-- Count_Invited 的总计数 = 0 + Count_Invited = 1 + Count_Invited = 5
-- 现在假设 AmountPersons 的计数现在是 40
-- 这意味着不是每个 Count_Invited = 5 的人都可以被邀请,因为只有 10 个空位
-- 需要对这些行进行随机选择
-- 选择 Count_Invited 为 5 的随机行,直到这些行的总和为 10
-- 如果 10 不能匹配,则通过遍历剩余的行尽可能接近,但不要超过 10