随机选择,同时按多个组的百分比细分

时间:2010-01-13 20:30:24

标签: sql sql-server-2005 random weighted

我正在尝试为用户组建一个简单的系统,以生成将向其发送调查的用户列表。列表生成可以取决于各种约束。例如,“我们只想要来自美国和加拿大的人”或“我们只想要拥有2级或3级会员资格的人。”

这部分非常简单,我已经设置了表来捕获选择标准。但另一个标准是,他们可能希望获得每个项目的特定百分比。例如,“给我70%的美国用户和30%的加拿大用户。”再说一遍,我认为我可以毫不费力地做到这一点。他们会给出他们想要的用户数量,所以我可以按百分比加倍,然后确保数字在四舍五入后仍然加起来,我很乐意去。

考虑到未来,如果他们想要通过两组标准进行某些百分比细分,该怎么办?例如,“给我70%的美国,30%的加拿大,同时,50%的2级用户和50%的3级用户。”由于它不是当前的要求,我不打算让自己头疼,但如果有人有一个相当简单的算法(或SQL代码)来完成这样的事情,那么我很乐意看到它。

虽然我更喜欢与数据库无关的解决方案,但我使用的是MS SQL 2005,因此特定于该RDBMS的解​​决方案也很好。

我目前使用的表结构类似于:

CREATE TABLE Selection_Templates
(
     template_code     VARCHAR(20)     NOT NULL,
     template_name     VARCHAR(100)    NOT NULL,
     CONSTRAINT PK_Selection_Templates PRIMARY KEY CLUSTERED (template_code),
     CONSTRAINT UI_Selection_Templates UNIQUE (template_name)
)
GO
CREATE TABLE Selection_Template_Countries
(
     template_code            VARCHAR(20)       NOT NULL,
     country_code             CHAR(3)           NOT NULL,
     selection_percentage     DECIMAL(2, 2)     NULL,
     CONSTRAINT PK_Selection_Template_Countries PRIMARY KEY CLUSTERED (template_code, country_code),
     CONSTRAINT CK_Selection_Template_Countries_selection_percentage CHECK (selection_percentage > 0),
     CONSTRAINT FK_Selection_Template_Countries_Selection_Template FOREIGN KEY (template_code) REFERENCES Selection_Templates (template_code)
)
GO
CREATE TABLE Selection_Template_User_Levels
(
     template_code            VARCHAR(20)       NOT NULL,
     user_level               SMALLINT          NOT NULL,
     selection_percentage     DECIMAL(2, 2)     NULL,
     CONSTRAINT PK_Selection_Template_User_Levels PRIMARY KEY CLUSTERED (template_code, user_level),
     CONSTRAINT CK_Selection_Template_User_Levels_selection_percentage CHECK (selection_percentage > 0),
     CONSTRAINT FK_Selection_Template_User_Levels_Selection_Template FOREIGN KEY (template_code) REFERENCES Selection_Templates (template_code)
)

1 个答案:

答案 0 :(得分:2)

您可以将问题分解为四组随机用户:

  • 美国用户,级别2,选择所需总样本的35%
  • 加拿大用户,级别2,选择所需总样本的15%
  • 美国用户,级别3,选择所需总样本的35%
  • 加拿大用户,级别3,选择所需总样本的15%

如果有第三个标准,请将问题分解为八组。等等。

两个用户组,美国和加拿大,完全 50%2级和50%3级似乎是假的。因为它应该是随机的,你可能会期望它变化多一点。再加上来自加拿大的3级用户不是很多,占总数的15%呢?

随着标准变得越来越有选择性,你自然会从总样本的随机性中剔除。最终,您可以拥有一长串标准,这样您的用户中只有一个子集可以满足它,然后根本就没有随机性。


重新评论:对,SQL不是解决各种问题的最佳解决方案。使用迭代算法而不是单个基于集合的SQL查询处理问题可能会更好。例如:

  1. 选择一个随机行。
  2. 如果已在上一次迭代中选择了该行,则将其丢弃。
  3. 如果该行有助于保持选择70%美国,30%加拿大,50%2级,50%3级的总样本的速度,请保留它。否则,丢弃它。
  4. 如果达到所需的样本数量,请停止。
  5. 循环回到第1步。
  6. 当然,如果你选择一个有助于平衡70/30%国家比例的行,但会使50/50%的比例失衡,这会变得棘手。你丢弃它了吗?而且,当您只挑选前几行时,您可能还想忽略这些比率。

    正如@Hogan评论的那样,这可能是一个无法解决的NP-Complete问题。但是许多这样的问题都有一个解决方案可以给你一个“足够好”的结果,尽管不是一个可证明的最佳结果。