随机查询每次返回相同的记录

Posted

技术标签:

【中文标题】随机查询每次返回相同的记录【英文标题】:Random query returns same records each time 【发布时间】:2017-08-27 08:42:49 【问题描述】:

https://***.com/a/9937425/159072

我正在使用以下查询从表中选择 5 条随机记录,

SELECT Top 5 *
FROM   (SELECT *,
           Rnd(ID) AS RandomValue
        FROM   Words)
ORDER  BY RandomValue 

此查询在 MS Access 中运行良好。

但是,当我在 c# 应用程序中使用它时,就会出现问题。它每次返回相同的 5 条记录。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Text;

namespace MicrosiftAccessDbProviderFactory______Test

    public class MyClass 
    
        public int ID  get; set; 
        public string Name  get; set; 
    

    public class Program
    
        static void Main(string[] args)
        
            string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\db1.mdb;Persist Security Info=False";
            string providerName = @"System.Data.OleDb";
            DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);

            IDbConnection Connection = factory.CreateConnection();
            Connection.ConnectionString = connString;
            Connection.Open();

            IDbTransaction Transaction = Connection.BeginTransaction();

            IDbCommand Command = factory.CreateCommand();
            Command.Connection = Connection;
            Command.Transaction = Transaction;

            int count = 5;

            Command.CommandText = @"SELECT Top " + count + @" ID, Name
                                    FROM   (SELECT *,
                                               Rnd(ID) AS RandomValue
                                            FROM   Words)
                                    ORDER  BY RandomValue";
            IDataReader dataReader = Command.ExecuteReader();
            IList<MyClass> list = null;
            MyClass item = null;
            while (dataReader.Read())
            
                if (list == null)
                
                    list = new List<MyClass>();
                

                item = new MyClass();
                item.ID = dataReader.GetInt32(0);
                item.Name = dataReader.GetString(1);

                list.Add(item);
            

            dataReader.Close();

            Transaction.Commit();

            string str = string.Empty;
        
    

我该如何解决这个问题?

【问题讨论】:

看起来您正在使用两个不同的表格(MyTable 和 Words)。 @jdweng,打错字了。 【参考方案1】:

你需要salt Rnd 函数,比如:

SELECT * FROM SomeTable ORDER BY Rnd(-Timer()*[ID])

因此,在您的查询中:

Command.CommandText = @"SELECT Top " + count + @" ID, [Name]
                        FROM Words
                        ORDER BY Rnd(-Timer()*[ID])";

【讨论】:

【参考方案2】:

这让我很感兴趣。真正让我着迷的是为什么它可以在 Access 中工作。我可以理解为什么它不适用于 c#: rnd() 总是用相同的值初始化。我的解决方案很丑,但它有效。我希望有人会查看解决方案并了解如何改进它。至少它包含了一个想法的种子,如何在 Access 和 c# 之间进行这项工作。

第一步。

在 Access 中创建一个与目标表相同的表 (WordsGUID),但有一个额外的字段 RandomGUID,设置为数据类型自动编号,字段大小复制 ID。为了更好地衡量,我让它索引没有重复,但我怀疑这是必要的。

第 2 步。

在 C# 中插入以下内容

Command.CommandText ="DELETE FROM WordsGUID";
Command.ExecuteNonQuery();

Command.CommandText ="INSERT INTO WordsGUID SELECT * FROM Words";
Command.ExecuteNonQuery();

Command.CommandText ="SELECT TOP 5 * FROM WordsGUID ORDER BY RandomGUID";
IDataReader dataReader = Command.ExecuteReader();

等等。

正如我所说的丑陋,如果你有一张大桌子,可能会慢得可怕,但我想不出更好的了!

【讨论】:

你可以在一个SELECT top 5 * FROM Words order by newid() 中完成这 3 个步骤(至少,这在 MS SQL 中有效;我已经多年没有使用 Access)。 @JohnLBevan 不幸的是,Access 中没有 NewId()

以上是关于随机查询每次返回相同的记录的主要内容,如果未能解决你的问题,请参考以下文章

使用子查询提取随机值每次都显示相同的值

使用子查询来拉随机值每次都会显示相同的值

Impala 查询以随机顺序返回数据

掷骰子程序在每次运行时生成相同的随机数序列

按随机和字段排序 MySQL 查询?

在 Appengine 数据存储上查询 N 条随机记录