2010-07-09 82 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); 

於加權樣本,有偏好的最近的記錄(我錯過了這個先讀問題的時候),那麼馬丁的解決方案是更好的。

相關問題