用于根据多个条件选择随机样本的SQL存储过程

时间:2017-07-04 05:25:31

标签: sql-server tsql stored-procedures

我是SQL新手。我在互联网上寻找一个与我遇到的问题相匹配的解决方案,但我找不到任何问题。我在SQL Server 2012中有一个名为'tblItemReviewItems'的表。 tblItemReviewItems

信息
1. ItemReviewId列是PK 2.删除的列只有“是”和“否”值 3.经审计的列只有“是”和“否”值。

我想创建一个存储过程来执行以下操作:

  1. 为给定日期范围内的不同“UserId”和不同的“ReviewDate”选择所有ItemReviewId的10%的随机样本。 10%的样本应包括-5%的总人口来自删除(否)和5%的总人口来自删除(是)。审核=“是”将被排除在样本之外。< / LI>

    例如 - 用户有118条记录。在118条记录中,有17条记录已删除列值“否”,101条记录已删除列值“是”。我们需要随机抽取12条记录。在这12条记录中,6条应该已删除列值“否”,6条应该已删除列值“是”

    1. 将已审核的列值更新为“检查”所选样本。
    2. 我怎样才能做到这一点?

      这是我用来挑选5%已删除列值“No”和5%Deleted列值“Yes”的样本的存储过程。现在的情况有所不同。

      ALTER PROC [dbo].[spItemReviewQcPickSample]  
          (  
               @StartDate Datetime  
              ,@EndDate Datetime 
           )  
          AS  
          BEGIN  
          WITH CTE  
            AS (SELECT ItemReviewId  
                      ,100.0  
                      *row_number() OVER(PARTITION BY UserId  
                                                     ,ReviewDate  
                                                     ,Deleted  
                                             order by newid()  
                                        )
                      /count(*) OVER(PARTITION BY UserId  
                                                 ,Reviewdate  
                                                 ,Deleted  
                                    )  
                       AS pct  
                 FROM tblItemReviewItems  
                 WHERE ReviewDate BETWEEN @StartDate AND @EndDate  
                   AND Deleted in ('Yes','No')  
                   AND Audited='No'  
               )  
          SELECT a.*  
            FROM tblItemReviewItems AS a  
                 INNER JOIN cte AS b  
                         ON b.ItemReviewId=a.ItemReviewId  
                        AND b.pct<=6  
          ;  
          WITH CTE  
            AS (SELECT ItemReviewId  
                      ,100.00  
                      *row_number() OVER(PARTITION BY UserId  
                                                     ,ReviewDate  
                                                     ,Deleted  
                                             ORDER BY newid()  
                                        )
                      /COUNT(*) OVER(PARTITION BY UserId  
                                                 ,Reviewdate  
                                                 ,Deleted  
                                    )  
                       AS pct  
                  FROM tblItemReviewItems  
                 WHERE ReviewDate BETWEEN @StartDate AND @EndDate  
                   AND deleted IN ('Yes','No')  
                   AND audited='No'  
               )  
          UPDATE a  
             SET Audited='Check'  
            FROM tblItemReviewItems AS a  
                 INNER JOIN cte AS b  
                         ON b.ItemReviewId=a.ItemReviewId  
                        AND b.pct<=6  
          ;  
          END  
      

      任何帮助都将受到高度赞赏。提前谢谢。

1 个答案:

答案 0 :(得分:0)

这可能会帮助您入门。我的想法是,您创建所需的临时表,并将特定数据加载到(已删除,未删除等)中。然后你按照以下方式运行:

IF OBJECT_ID('tempdb..#tmpTest') IS NOT NULL DROP TABLE #tmpTest
GO
CREATE TABLE #tmpTest
(
    ID  INT                 ,
    Random_Order INT
)

INSERT INTO #tmpTest
(
    ID
)
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9 UNION ALL
SELECT 10 UNION ALL
SELECT 11 UNION ALL
SELECT 12 UNION ALL
SELECT 13 UNION ALL
SELECT 14 UNION ALL
SELECT 15 UNION ALL
SELECT 16;

DECLARE @intMinID   INT ,
        @intMaxID   INT;


SELECT  @intMinID = MIN(ID)
FROM    #tmpTest;

SELECT  @intMaxID = MAX(ID)
FROM    #tmpTest;

WHILE @intMinID <= @intMaxID

    BEGIN
        UPDATE  #tmpTest
        SET     Random_Order = 10 + CONVERT(INT, (30-10+1)*RAND())
        WHERE   ID = @intMinID;

        SELECT @intMinID = @intMinID + 1;
    END

SELECT      TOP 5 *
FROM        #tmpTest
ORDER BY    Random_Order;

这会为一个列分配一个随机数,然后与TOP 5子句一起使用,以获得随机前5个选择。

欣赏循环可能效率不高,但如果没有它,您可以更新为随机数,并且可以实现相同的原则。希望能给你一些想法。

相关问题