如何根据标准选择包含记录的TOP X?

时间:2012-09-11 18:10:59

标签: sql tsql select

我有一个包含多列的表,包括一个名为“PolicyNumber”的列

以下是一个示例:

PolicyNumber

NYH1111
NYD2222
SCH3333
SCS4444
LUH5555
LUS6666
ALH7777
ALW8888
VAH9999
AKH0000
...
NYH1010
NYD2318

此表中有1,000多条记录,记录包含每种策略编号类型中的几种。例如,多个策略以“NYH”开头,或多个策略以“VAH”开头。

可能的政策类型如下:

NYH
NYD
SCH
SCS
LUH
LUS
ALH
ALW
VAH
AKH

如何在每个政策类型中包含至少一个的SELECT TOP 300?请记住,策略类型是策略号的前3个字母。

这甚至可能吗?这样做的目的是我必须从生产中获取300条记录以转储到测试环境中,并且我需要包含每个策略中的至少1条。在我至少有一个之后,它可以完全随机化。

5 个答案:

答案 0 :(得分:1)

离开我的头顶,你可以这样做:

SELECT TOP 30 Column1, Column2, Column3, PolicyNumber
FROM YourTable
WHERE PolicyNumber LIKE 'NYH%'

UNION 

SELECT TOP 30 Column1, Column2, Column3, PolicyNumber
FROM YourTable
WHERE PolicyNumber LIKE 'NYD%'

UNION

/* ... remaining eight policy types go here */ 

ORDER BY PolicyNumber /* Or whatever sort order you want */

每次都会给你30种每种类型,而不是一种类型的X和另一种类型的Y.

答案 1 :(得分:1)

一种快速的方式让我想到..下面的查询每个策略类型只会获取1条记录

 SELECT TOP 300 *

 FROM   ( SELECT *,rank1= ROW_NUMBER () OVER (PARTITION BY LEFT (PolicyNo,3) ORDER BY GETDATE ()) FROM MyTable
        ) AS t1

 WHERE  t1.rank1 = 1

答案 2 :(得分:1)

尝试使用SQL Server 2005 +:

;WITH CTE AS
(
    SELECT  LEFT(PolicyNumber) PolicyType, PolicyNumber, 
            ROW_NUMBER() OVER(PARTITION BY LEFT(PolicyNumber) ORDER BY NEWID()) RN
    FROM YourTable
)
SELECT TOP 300 PolicyNumber
FROM CTE
ORDER BY RN, NEWID()

答案 3 :(得分:1)

你可以试试这个:

首先在此解决方案中有newid(),您可以在每次运行时生成随机顺序。

为了实现“每个政策中至少有一个”目标,我创建了AtLeastOne列。这将从随机CTE表中为开头的每个唯一三个字母选择第一个。如果当前Policy等于第一个选定值,那么它得到1,否则为0.因此,使用此逻辑,您可以从每个唯一的三个字母中选择随机化的第一个。

注意:如果您只需要“策略”字段,也可以将此逻辑直接放入Order By部分。 (我通过这种方式制作了示例,使其背后的逻辑可见)

在最后一步中,您只需按AtLeastOne Des c排序,然后按随机ID排序。

WITH CTE_Policy
AS
(
  SELECT newid() as  ID, Policy
  FROM Code
)
SELECT TOP 300
Policy,
CASE WHEN Policy = (SELECT TOP 1 Policy FROM cte_Policy c
                    WHERE SUBSTRING(c.Policy,1,3) = 
                      SUBSTRING(CTE_Policy.Policy,1,3))
THEN 1 ELSE 0 END  AS AtLeastOne

FROM CTE_Policy
ORDER BY AtLeastOne DESC, ID

这是SQLFiddle demo

答案 4 :(得分:1)

借用ClearLogic +1如果有效,请将支票交给ClearLogic

WHERE t1.rank1 = 1的问题是,如果少于300个唯一的话,它会停止300个

 SELECT TOP 300 t1.PolicyNo

 FROM   ( SELECT PolicyNo, rank1= ROW_NUMBER () 
          OVER (PARTITION BY LEFT (PolicyNo,3) ORDER BY NEWID()) 
          FROM MyTable
        ) AS t1

 order by t1.rank, t1.PolicyNo