2009-11-16 47 views
0

我有一個表隨機排序每次查詢在MS-訪問數據庫運行

num weight 
1  12 
4  13 
2  13 
6  9 
7  13 

我如何寫一個查詢,這將根據體重以降序對錶進行排序。但數字4,2和7具有相同的權重(13),因此每次運行查詢時都必須對它們進行隨機排序。

任何幫助表示讚賞。

回答

2

通常,您的SQL將包含某種隨機函數(它看起來像Access有rnd()函數)。

所以,你可以使用:

select num, weight, rnd(num) 
from tbl 
order by weight desc, 3 

這將讓你看到用於測試目的河在實際的查詢結果,你可能只是想使用類似:

select num, weight 
from tbl 
order by weight desc, rnd(num) 

this page

當值大於0,賽第一輪()返回一個隨機數。
當值小於0時,Rnd()根據值返回相同的隨機數。如果值只出現一次,您將不會注意到這種行爲。訪問也重置種子,這意味着序列重新開始。
當值等於0,Rnd函數()返回最近生成的隨機數

更新1:是否rnd()在下面的查詢或每行一次執行一次我不確定 - 該文件不清楚。評論似乎表明,所有行都收到相同的結果,表明它可能是後者。它可能是將其更改爲rnd(num)rnd(abs(num)+1)將解決該問題。我必須檢查何時安裝了Access的盒子。

更新2:我現在已經在Access 2007中進行了測試,它確實在使用rnd(1)時爲每一行提供相同的隨機值。它確實每次運行查詢時給出不同的rnd(num)值,並且各行獲得不同的值。因此,你需要查詢的是:

select num, weight from tbl order by weight desc, rnd(num); 

如果你創建一個表有兩個Number字段,然後運行在它該查詢,你會看到頻繁地刷新(與F5)將交換圍繞274行,但將16行保留在同一位置,因爲前三位的權重均爲13,最後兩位的權重分別爲129

我已更新上述查詢以匹配此新信息。

+0

種子1將產生每個記錄相同的隨機NR。你可以使用num * weight代替 – marg 2009-11-16 03:00:11

+0

@marg,種子沒有設置爲正數,只有負數(見鏈接頁面的引用),rnd(1)每次會產生一個不同的數字。 – paxdiablo 2009-11-16 05:27:16

+0

marg是正確的num *權重我得到了與rnd(1)相同的隨機數 – silverkid 2009-11-16 06:26:33

0

我認爲這樣做會訣竅...

ORDER BY weight, Rnd() 
0

當從Access UI以外Access數據庫引擎SQL使用RND(),隨機數的相同順序將每個會話使用(沒有用於VBA的隨機化沒有原生支持)。

例如,連接到源,然後陸續執行SELECT RND();三次,你會得到以下值:

0.705547511577606 
0.533424019813538 
0.579518616199493 

關閉的連接,連接到源再次然後再次執行相同的查詢三次您將按照相同的順序獲得與上述相同的三個值。

在知道這些值可預測的情況下,我們可以證明每次引用它時都會使用不同的值RND()。考慮此查詢:

SELECT RND() 
    FROM T 
WHERE RND() > CDBL(0.6); 

我們知道,在一個新的會話中的第一個值將是0.705547511577606,因此表達

RND() > CDBL(0.6)

將評估TRUE。然而,對於表T中的每一行重複值0.533424019813538,該值不滿足WHERE子句!所以很明顯,WHERE子句中的RND()的值與SELECT子句中的值不同。完整的代碼發佈在下面。

注意我想知道是否可以使用CURRENT_TIMESTAMP值的最不重要部分生成一個隨機數,該值可以在單個查詢的範圍內一致使用,並且對於會話不可預測,如RND()所示。但是,Jet數據庫引擎不支持它和它最接近的比喻,NOW()功能,不具備足夠的粒度是有用:(

Sub jmgirpjpo() 

    On Error Resume Next 
    Kill Environ$("temp") & "\DropMe.mdb" 
    On Error GoTo 0 

    Dim cat 
    Set cat = CreateObject("ADOX.Catalog") 

    With cat 

    .Create _ 
     "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
     "Data Source=" & _ 
     Environ$("temp") & "\DropMe.mdb" 

    With .ActiveConnection 

     .Execute "CREATE TABLE T (T INT);" 
     .Execute "INSERT INTO T VALUES (1);" 
     .Execute "INSERT INTO T VALUES (2);" 
     .Execute "INSERT INTO T VALUES (3);" 

     Dim rs 
     Set rs = .Execute("SELECT RND() FROM T WHERE RND() > CDBL(0.6);") 
     MsgBox rs.GetString 

    End With 
    End With 

End Sub 
+0

您是否可以從外部Jet/ACE傳遞列值,即原始表示例中的Rnd(num)? – 2009-11-17 03:43:47

+0

是的,但不會改變其種子價值。 – onedaywhen 2009-11-17 08:47:29