我需要根据样本大小返回一些值。因此,如果用户选择5%,他们将获得查询,从而导致来自原始查询的随机5%的行。有没有办法只用sql来实现这个目标?
目前,该过程是运行查询然后生成随机数以删除行,直到只剩下5%,然后从剩下的行构建新查询。我不相信这是最有效的方式,更好的想法?
由于
答案 0 :(得分:3)
什么是后端?有些人支持这种开箱即用,例如。 SQL Server Limiting Result Sets by Using TABLESAMPLE:
SELECT FirstName, LastName
FROM Person.Person
TABLESAMPLE (5 PERCENT) ;
在任何系统中,您都应该尝试在服务器上进行过滤,而不是在客户端上进行过滤。例如。您可以使用MySQL CRC32
来计算行校验和,然后使用此校验和来限定5%的行。或者使用RAND()
来达到类似的效果。无论你做什么,只是不要获取整个表并过滤客户端上的行。
答案 1 :(得分:0)
@Remus Rusanu在使用数据库服务器方面拥有最佳方法。但是如果你在应用服务器上做,这是一个依赖CF的方法。它会回退所有ID,这比获取每条记录的整行要小,对这些ID进行采样,然后返回数据库以获取完整记录。
<cfquery name="data" datasource="#dsn#">
SELECT id FROM myTable
</cfquery>
<cfset sampleSize = ceiling(data.recordcount * .05)>
<cfset idsInterred = 0>
<cfset ids = {}>
<cfloop condition="idsInterred LT sampleSize">
<cfset newId = data['id'][randRange(1, sampleSize)]>
<cfif NOT structKeyExists(ids, newId)>
<cfset idsInterred++>
<cfset ids[newId] = true>
</cfif>
</cfloop>
<cfquery name="data" datasource="#dsn#">
SELECT *
FROM myTable
<!--- assuming ids are integers --->
WHERE id IN (#structKeyList(ids)#)
</cfquery>
<cfloop query="data">
<!--- do stuff here --->
</cfloop>