Самый эффективный способ вернуть случайный конкретный размер выборки в sql / coldfusion - PullRequest
0 голосов
/ 07 марта 2011

Мне нужно вернуть некоторые значения в зависимости от размера выборки. Таким образом, если пользователь выберет 5%, он получит запрос, в результате чего в исходном запросе получится 5% случайных строк. Есть ли способ, которым я могу достичь этого только с помощью sql?

В настоящее время процесс состоит в том, чтобы выполнить запрос, затем сгенерировать случайные числа для удаления строк, пока не останется только 5%, а затем создать новый запрос из оставшихся строк. Я не верю, что это самый эффективный способ, есть идеи получше?

Спасибо

Ответы [ 2 ]

3 голосов
/ 07 марта 2011

Какой бэкэнд?Некоторые поддерживают это из коробки, например. Ограничение результирующих наборов SQL Server с использованием TABLESAMPLE :

SELECT FirstName, LastName
FROM Person.Person 
TABLESAMPLE (5 PERCENT) ;

В любой системе вы должны пытаться фильтровать на сервере, а не на клиенте.Например.Вы можете использовать MySQLs CRC32 для вычисления контрольной суммы строки, а затем использовать эту контрольную сумму для определения 5% строк.Или используйте RAND() для аналогичного эффекта.Что бы вы ни делали, просто не извлекайте всю таблицу и не фильтруйте строки на клиенте.

0 голосов
/ 07 марта 2011

@ Remus Rusanu имеет лучший подход с точки зрения использования сервера базы данных.Но если вы делаете на сервере приложений, вот метод, основанный на CF.Он извлекает все идентификаторы, которые меньше, чем получение всей строки для каждой записи, отбирает их и затем возвращается в базу данных для полных записей.

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...