我有一个表随机排序每次查询在MS-访问数据库运行
num weight
1 12
4 13
2 13
6 9
7 13
我如何写一个查询,这将根据体重以降序对表进行排序。但数字4,2和7具有相同的权重(13),因此每次运行查询时都必须对它们进行随机排序。
任何帮助表示赞赏。
我有一个表随机排序每次查询在MS-访问数据库运行
num weight
1 12
4 13
2 13
6 9
7 13
我如何写一个查询,这将根据体重以降序对表进行排序。但数字4,2和7具有相同的权重(13),因此每次运行查询时都必须对它们进行随机排序。
任何帮助表示赞赏。
通常,您的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)
当值大于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
)将交换围绕2
,7
和4
行,但将1
和6
行保留在同一位置,因为前三位的权重均为13
,最后两位的权重分别为12
和9
。
我已更新上述查询以匹配此新信息。
我认为这样做会诀窍...
ORDER BY weight, Rnd()
当从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
您是否可以从外部Jet/ACE传递列值,即原始表示例中的Rnd(num)? – 2009-11-17 03:43:47
是的,但不会改变其种子价值。 – onedaywhen 2009-11-17 08:47:29
种子1将产生每个记录相同的随机NR。你可以使用num * weight代替 – marg 2009-11-16 03:00:11
@marg,种子没有设置为正数,只有负数(见链接页面的引用),rnd(1)每次会产生一个不同的数字。 – paxdiablo 2009-11-16 05:27:16
marg是正确的num *权重我得到了与rnd(1)相同的随机数 – silverkid 2009-11-16 06:26:33