从t sql中的较大表中采样

时间:2015-01-09 05:22:17

标签: sql-server tsql sampling

我需要从完整的客户表(Full_Table)创建一个较小的客户表(我们称之为New_Table)。

所有客户都有不同的年龄。在我的New_Table中,我们需要一定的年龄分布,因此在为New_Table选择客户时,我需要指定我们需要10%的“15岁以下”客户,20%的客户来自“15到24”和等等。

问题是 - 我们需要从每个年龄组中获取的客户的确切百分比因报告而异 - 所以在我的查询中,我不能只指定我需要选择的每个组的百分比。

有什么方法可以编写一个查询,其中每个组的客户所需百分比是通过子查询计算的,还是仅从一个单独的表中获取?

非常感谢您的帮助!!

1 个答案:

答案 0 :(得分:0)

我在这个例子中使用SQL Server 2008。

使用示例数据创建表

DECLARE @Full TABLE (ID int IDENTITY(1,1), AgeGroup nvarchar(50));

INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');
INSERT INTO @Full (AgeGroup) VALUES ('Under 15');

INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');
INSERT INTO @Full (AgeGroup) VALUES ('15 to 24');

INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');
INSERT INTO @Full (AgeGroup) VALUES ('24 to 35');

此表有三行,适用于三个年龄组,共30行。通常情况下,您将拥有一个包含所有可能年龄组列表的查找表,而在Full表中您将拥有AgeGroupID而不是文本。为简单起见,我将使用纯文本。

您的程序将有一个参数 - 一个包含年龄组和每组所需百分比的表。 我将创建一个存储过程并将一个表值参数传递给它。这里只是脚本中的另一个表。

DECLARE @Params TABLE (AgeGroup nvarchar(50), Percentage float);

INSERT INTO @Params (AgeGroup, Percentage) VALUES ('Under 15', 0.1);
INSERT INTO @Params (AgeGroup, Percentage) VALUES ('15 to 24', 0.2);
INSERT INTO @Params (AgeGroup, Percentage) VALUES ('24 to 35', 0.4);

对于Params表中的每一行,我们希望从Full表中获取一些行。 CROSS APPLY有效地为Params中的每一行运行给定的子查询。返回的行数由TOP子句确定:

SELECT *
FROM
    @Params AS P
    CROSS APPLY
    (
        SELECT TOP(P.Percentage * 100) PERCENT
            F.ID
        FROM @Full AS F
        WHERE F.AgeGroup = P.AgeGroup
        ORDER BY F.ID
    ) AS CA_Full
;

这是结果集:

AgeGroup    Percentage    ID
Under 15    0.1           1
15 to 24    0.2           11
15 to 24    0.2           12
24 to 35    0.4           21
24 to 35    0.4           22
24 to 35    0.4           23
24 to 35    0.4           24

您可以看到每个年龄组的行数对应于给定的百分比。

要将此结果插入New表,请使用标准INSERT INTO New SELECT ... FROM ...