得到随机前n行,其中n大于表中的行数

时间:2015-01-23 21:59:08

标签: sql sql-server top-n

我正在编写一个生成随机数据的脚本。我有两个表,一个存储名字,第二个存储姓氏。 我想得到例如1000个随机对的名字和姓氏。我可以使用以下代码实现它:

    with x as (
    select top 1000 f.firstName from dbo.firstNames f order by newid()
    ), xx as (
    select x.firstName, row_number() over(order by x.firstName) as nameNo from x
    ), y as (
    select top 1000 s.surName from dbo.surNames s order by newid()
    ), yy as (
    select y.surName, row_number() over(order by y.ulica) as nameNo from y
    )
    select xx.firstName, yy.surName 
    from xx inner join yy on (xx.nameNo=yy.nameNo)

...但是如果我的一个表包含少于1000行呢? 我想知道如何从表中获得超过n行,其中n小于表/视图中的行数,并且您不会介意重复的结果。 我能想到的唯一方法是使用临时表和while循环,并用随机行填充它,直到有足够的行。但我想知道是否可以通过一个选择来做到这一点?我目前在我的电脑上使用sql server 2012,但如果我能在sql server 2008下运行它,我将不胜感激。

2 个答案:

答案 0 :(得分:3)

您可以在交叉加入后进行随机化

select top 1000 fn.firstname, sn.surname
from firstnames fn cross join
     surnames sn
order by newid();

我是第一个承认这种方法的问题是性能的问题,但它确实在理论上有效。如果表格最多只有几百行,那么性能可能会很好。

答案 1 :(得分:2)

如果你想要1000个随机对,那么每个表中的32个就足够了(32 * 32 = 1024):

WITH f1 AS (
    SELECT TOP 32 firstName FROM dbo.firstName ORDER BY newid()
), s1 AS
    SELECT TOP 32 surName FROM dbo.surName ORDER BY newid()
)
SELECT f1.firstName, s1.surName
  FROM f1 CROSS JOIN s1;

如果这不够随意,那么您可以尝试以下方法:

WITH f1 AS (
    SELECT TOP 100 firstName FROM dbo.firstName ORDER BY newid()
), s1 AS
    SELECT TOP 100 surName FROM dbo.surName ORDER BY newid()
)
SELECT TOP 1000 f1.firstName, s1.surName
  FROM f1 CROSS JOIN s1
 ORDER BY newid();

以上将获得10,000种组合并随机选择1,000种。