我想为百分比分配随机分配记录名称。例如,假设我有以下数据:
/** @test */
public function an_user_can_verify_his_email_address()
{
$notification = new EmailVerificationNotification();
$user = factory(User::class)->create(['email_verified_at' => null]);
$uri = $notification->verificationUrl($user);
$this->assertSame(null, $user->email_verified_at);
$this->actingAs($user)->get($uri);
$this->assertNotNull($user->email_verified_at);
}
我想为NO名称记录分配一个随机名称,该名称基于type,sub_type和reg类别分组中的pct分布。因此,例如,当类型= xx,sub_type = cc和reg = n时,四个NO名称记录将被随机分配名称a或b,但是在类型= xx,sub_type = cc和reg = n分组将为a的70%和b的30%,因为那是它们在该分组内的pct值。因此,在给定分组中名称pct分配的情况下,按类型/ sub_type / reg分组按名称随机分配记录。
结果可能看起来像这样:
name type sub_type reg pct
a xx yy n .7
a xx yy n .7
NO Name xx yy n NULL
NO Name xx yy n NULL
NO Name xx yy n NULL
b xx yy n .3
NO Name xx yy n NULL
a bb yy n .1
b bb yy n .8
c bb yy n .1
NO Name bb yy n NULL
a xx cc n .1
a xx cc n .1
NO Name xx cc n NULL
NO Name xx cc n NULL
NO Name xx cc n NULL
b xx cc n .9
NO Name xx cc n NULL
a bb cc n .5
b bb cc n .2
c bb cc n .3
NO Name bb cc n NULL
a xx cc x .2
a xx cc x .2
NO Name xx cc x NULL
NO Name xx cc x NULL
NO Name xx cc x NULL
b xx cc x .8
NO Name xx cc x NULL
a bb cc x .3
b bb cc x .1
c bb cc x .6
NO Name bb cc x NULL
我在构成的数据中没有足够的记录来真正显示分布,但希望足以说明我的问题。
这与我想要的操作类似,但是百分比在此示例中是固定的,并且与我没有的任何组一样: Divide the Table data randomly based on percentages
希望这是有道理的。
编辑1:我想我的水桶部分倒了
name type sub_type reg pct
a xx yy n .7
a xx yy n .7
a xx yy n NULL
a xx yy n NULL
a xx yy n NULL
b xx yy n .3
b xx yy n NULL
a bb yy n .1
b bb yy n .8
c bb yy n .1
b bb yy n NULL
a xx cc n .1
a xx cc n .1
b xx cc n NULL
b xx cc n NULL
b xx cc n NULL
b xx cc n .9
b xx cc n NULL
a bb cc n .5
b bb cc n .2
c bb cc n .3
a bb cc n NULL
a xx cc x .2
a xx cc x .2
b xx cc x NULL
b xx cc x NULL
b xx cc x NULL
b xx cc x .8
a xx cc x NULL
a bb cc x .3
b bb cc x .1
c bb cc x .6
c bb cc x NULL
答案 0 :(得分:0)
也许此代码段返回您正在寻找的结果
它的逻辑与您之前引用的其他答案略有不同。但是,我认为在当前情况下,ROW_NUMBER
是NTILE
;WITH cte ([name], [type], sub_type, reg, pct)
AS
(
SELECT 'a', 'xx', 'yy', 'n', .7 UNION ALL
SELECT 'a', 'xx', 'yy', 'n', .7 UNION ALL
SELECT 'NO Name', 'xx', 'yy', 'n', NULL UNION ALL
SELECT 'NO Name', 'xx', 'yy', 'n', NULL UNION ALL
SELECT 'NO Name', 'xx', 'yy', 'n', NULL UNION ALL
SELECT 'b', 'xx', 'yy', 'n', .3 UNION ALL
SELECT 'NO Name', 'xx', 'yy', 'n', NULL UNION ALL
SELECT 'a', 'bb', 'yy', 'n', .1 UNION ALL
SELECT 'b', 'bb', 'yy', 'n', .8 UNION ALL
SELECT 'c', 'bb', 'yy', 'n', .1 UNION ALL
SELECT 'NO Name', 'bb', 'yy', 'n', NULL UNION ALL
SELECT 'a', 'xx', 'cc', 'n', .1 UNION ALL
SELECT 'a', 'xx', 'cc', 'n', .1 UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'n', NULL UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'n', NULL UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'n', NULL UNION ALL
SELECT 'b', 'xx', 'cc', 'n', .9 UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'n', NULL UNION ALL
SELECT 'a', 'bb', 'cc', 'n', .5 UNION ALL
SELECT 'b', 'bb', 'cc', 'n', .2 UNION ALL
SELECT 'c', 'bb', 'cc', 'n', .3 UNION ALL
SELECT 'NO Name', 'bb', 'cc', 'n', NULL UNION ALL
SELECT 'a', 'xx', 'cc', 'x', .2 UNION ALL
SELECT 'a', 'xx', 'cc', 'x', .2 UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'x', NULL UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'x', NULL UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'x', NULL UNION ALL
SELECT 'b', 'xx', 'cc', 'x', .8 UNION ALL
SELECT 'NO Name', 'xx', 'cc', 'x', NULL UNION ALL
SELECT 'a', 'bb', 'cc', 'x', .3 UNION ALL
SELECT 'b', 'bb', 'cc', 'x', .1 UNION ALL
SELECT 'c', 'bb', 'cc', 'x', .6 UNION ALL
SELECT 'NO Name', 'bb', 'cc', 'x', NULL
)
-- Records without name
SELECT CASE
WHEN d.TotalRecordsInGroup = 1 THEN 'a' --only one record in the group
WHEN d.RecordNr/CAST(d.TotalRecordsInGroup AS FLOAT) < .7 THEN 'a'
WHEN d.RecordNr/CAST(d.TotalRecordsInGroup AS FLOAT) <= 1.0 THEN 'b'
ELSE NULL
END AS [name]
,
d.type,
d.sub_type,
d.reg,
d.pct
FROM (
SELECT cte.name
, cte.type
, cte.sub_type
, cte.reg
, cte.pct
-- obtain record number randomly of members in a group
, ROW_NUMBER() OVER (PARTITION BY type, cte.sub_type,reg ORDER BY NEWID()) AS RecordNr
-- obtain the numbers of members in a group
, COUNT(*) OVER (PARTITION BY type, cte.sub_type,reg) AS TotalRecordsInGroup
FROM cte
WHERE cte.name = 'No Name'
) d
UNION ALL
-- Records with a known name
SELECT cte.name,
cte.type,
cte.sub_type,
cte.reg,
cte.pct
FROM cte
WHERE cte.name <> 'No Name'
ORDER BY d.type, sub_type, reg