2010-07-09 83 views
4

有没有办法从数据库表中显示一定数量的随机记录,但是很受创建日期和时间的影响。是否有用于显示伪随机数据库记录的SQL Server功能?

例如:

  • 出10条随机的,但
  • 表示具有比最早

  • 更多的频率最新的说,有在news表100项

  • 最近(按日期时间)的记录几乎有100%被选中的几率
  • 第一(由日期时间)记录将有被选择
  • 第50(由日期时间)记录的几乎0%的机会将有被选择

的50%的机会是存在于MSSQL这样的事直?或者是否有一些功能(最佳做法)在C#我可以使用这个?

日Thnx

** 编辑:标题实在是太可怕了,我知道了。如果您有更具描述性的内容,请修改。 thnx

+0

我们在谈论多少条记录?是否附有数字ID? – aronchick 2010-07-09 22:01:53

+6

一个简单的方法是根据你想要多少元素来选择元素中的每一个元素。然后你总结所有这些权重,并在该范围内选择一个随机数。然后再次遍历所有元素,找出实际选取的元素。例如,3个元素的权重分别为25,25和50.您随机选取了第37个元素,这个元素位于第2个元素(25-49,含)之内。 – 2010-07-09 22:02:43

+0

@aronchick记录可以从1到最大诠释我猜:P – b0x0rz 2010-07-09 22:05:31

回答

4

一个相当简单化的方式可能如下所示。或者至少它可能会给你一个开始的基础。

WITH N AS 
(
SELECT id, 
     headline, 
     created_date, 
     POWER(ROW_NUMBER() OVER (ORDER BY created_date ASC),2) * /*row number squared*/ 
      ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS [Weight] /*Random Number*/ 
    FROM news 
) 
    SELECT TOP 10 
     id, 
     headline, 
     created_date FROM N 
    ORDER BY [Weight] DESC 
+1

+1这是要走的路,但为什么使用NEWID()复杂化并不使用RAND()? http://msdn.microsoft.com/en-us/library/ms177610.aspx – 2010-07-09 23:42:44

+0

@Remus。我认为兰德()只评估一次,所以总是会返回相同的结果集http://www.sql-server-helper.com/tips/generate-random-numbers.aspx – 2010-07-09 23:49:43

+0

我明白了。我猜你总是可以强迫它依赖于一个列,例如:'select rand(binary_checksum(getdate(),object_id)),* from sys.tables',但与使用newid() – 2010-07-09 23:57:57

0

您可以使用指数分布(例如)和SELECT TOP(N)按日期排序,然后选择最后一行。 您可以根据现有行数选择指数。

+0

这只会给你一个不同数量的最近结果... – 2010-07-09 22:33:11

+0

@迈克尔 - 我说只挑最后一行。 – EFraim 2010-07-10 10:03:49

+0

对不起,你是对的。那么你是否建议一遍又一遍地重复这个操作来获得所需数量的最近结果?这听起来很贵。 – 2010-07-11 20:43:52

0

不幸的是我不知道MSSQL,但我可以给出一个高层次的建议。

  1. 获取UNIX时间日期(或其他一些增加积分表示)
  2. 鸿沟这个值由最大的各列得到的百分比。
  3. 获取一个随机数并乘以上述百分比。
  4. 按此值对您的列进行排序,然后取顶部N

这会给予最近的结果更多的权重。如果你想调整老的和后来的结果的相对频率,你可以在得到这个比率之前对这些值应用指数或对数函数。如果您有兴趣,请告诉我,我可以提供更多信息。

0

如果您可以在数据库访问后过滤结果,或者您可以使用order by提交查询并使用读取器处理结果,则可以向选择添加概率偏差。你看到偏差越高,在if里面的测试越难,这个过程就越随机。

var table = ... // This is ordered with latest records first 
int nItems = 10; // Number of items you want 
double bias = 0.5; // The probabilistic bias: 0=deterministic (top nItems), 1=totally random 
Random rand = new Random(); 

var results = new List<DataRow>(); // For example... 

for(int i=0; i<table.Rows.Count && results.Count < nItems; i++) { 
    if(rand.NextDouble() > bias) 
     // Pick the current item probabilistically 
     results.Add(table.Rows[i]); // Or reader.Next()[...] 
} 
+0

如果表格比客户端进程可用地址空间大,该怎么办? – 2010-07-09 23:59:19

+0

好点。它也可以通过阅读器顺序访问。 – Mau 2010-07-10 10:14:06

2

对于随机样本,请参见Limiting Result Sets by Using TABLESAMPLE。例如。从表中选择100行的样本:

SELECT FirstName, LastName 
FROM Person.Person 
TABLESAMPLE (100 ROWS); 

于加权样本,有偏好的最近的记录(我错过了这个先读问题的时候),那么马丁的解决方案是更好的。

相关问题