Ms sql random: SQL Server функция RAND — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite
генерация псевдослучайных данных с использованием newID(). Возможности и подводные камни / Хабр
Известно, что встроенная функция newID() широко используется разработчиками не только по прямому назначению — то есть для генерации уникальных первичных ключей, но и в качестве средства для генерации массивов псевдослучайных данных.
В составе встроенных функций, newID() фактически единственная, которая не только non-deterministic, но можно сказать и «super-non-deterministic», т.к. в отличие от всех остальных, она способна выдавать новое значение для каждой новой строки, а не одно и то же для всего батча — что делает ее чрезвычайно полезной для подобной массовой генерации. Кроме newID() этим свойством обладает еще newSequentialID(), однако ее использование где-либо, кроме как в задании дефолтного значения колонок типа uniqueidentifier, запрещено.
За примерами далеко ходить не надо — ниже код:
SELECT TOP 100 ABS(CHECKSUM(NEWID())) % 1000
FROM sysobjects A
CROSS JOIN sysobjects B
или вот этот (если кажется, что checksum — трудоемкая операция):
SELECT TOP 100 ABS(CONVERT(INT, (CONVERT(BINARY(4), (NEWID()))))) % 1000
FROM sysobjects A
CROSS JOIN sysobjects B
Сгенерирует нам таблицу из 100 случайных целых чисел в диапазоне от 0 до 999.
Для плавающих чисел можно использовать свойство функции rand() инициализировать генератор целым числом:
SELECT TOP 100 RAND(CHECKSUM(NEWID()))
FROM sysobjects A
CROSS JOIN sysobjects B
В данном случае rand() используется по сути просто как преобразователь диапазона int32 в диапазон [0..1). Статистическая проверка качества распределения этим методом на количестве записей порядка миллиона показывает, что оно не уступает стандартному использованию rand(), инициализированному один раз, и далее используемому в цикле. Поэтому — можете смело использовать.
Еще один интересный вариант — генерация нормально-распределенных данных. Здесь будем использовать метод Бокса-Мюллера:
SELECT TOP 1000
COS(2 * PI() * RAND(BINARY_CHECKSUM(NEWID()))) *
SQRT(-2 * LOG(RAND(BINARY_CHECKSUM(NEWID()))))
FROM sysobjects A
CROSS JOIN sysobjects B
CROSS JOIN sysobjects C
Желающие могут проверить, что сгенерированное распределение очень близко к нормальному, построив график.
Все это хорошо работает и позволяет очень быстро сгенерировать хоть десяток миллионов записей, не используя решения «в лоб» типа циклов, курсоров, или даже вставки записей по одной в базу из слоя приложения. Нужно только убедиться, что таблицы, которые вы используете как источник строк, имеют достаточную емкость, и либо увеличить количество CROSS JOIN’ов, либо использовать табличные переменные с нужным количеством строк в качестве источника.
Однако, тема не только об этом. В подавляющем большинстве случаев сгенерированные строки материализуются, то есть вставляются в постоянную или временную таблицу, либо в табличную переменную. Если это так, то дальше можно не читать — материализованные данные будут работать отлично. Однако, встречаются случаи, когда вышеуказанные стейтменты используются в подзапросах. И вот здесь появляются труднообъяснимые на первый взгляд особенности поведения SQL engine. Рассмотрим их на примерах, а затем попытаемся проанализировать, почему так происходит, и как с этим бороться:
Для начала просто напишем statement с newID() в subquery и запустим его несколько раз в цикле:
declare @c int = 0
while @c < 5
begin
SELECT *
FROM (
SELECT ABS(CONVERT(INT, CONVERT(BINARY(4), NEWID()))) % 5 AS RNDIDX
FROM (
SELECT 1 AS ID
) ROWSRC
) SUBQ
set @c = @c + 1
end
Код работает ожидаемо — выдает 5 резалтсетов, в каждом строго одна запись с числом в диапазоне от 0 до 4. Скриншота результатов я не привожу — когда и так все в порядке, смысла в них мало.
Теперь интереснее. Пробуем поджойнить результат из SUBQ на какую-нибудь другую таблицу. Ее можно создать, а можно поджойнить subquery на subquery — результат от этого не изменится. Пишем:
declare @c int = 0
while @c < 5
begin
SELECT *
FROM (
SELECT ABS(CONVERT(INT, CONVERT(BINARY(4), NEWID()))) % 5 AS RNDIDX
FROM (
SELECT 1 AS ID
) ROWSRC
) SUBQ
INNER JOIN (
SELECT 0 AS VAL
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) NUM ON SUBQ.RNDIDX = NUM.VAL
set @c = @c + 1
end
Смоторим на скриншот результата выполнения — и медленно сползаем под стул — количество строк в каждом резалтсете не равно строго 1. Где-то пусто (это еще можно хоть как-то объяснить — не сработал INNER JOIN из-за выхода RNDIDX из диапазона [0..4] (что само по себе невероятно!)), а где-то — больше одной (!) записи.
Теперь делаем невинное изменение — меняем INNER на LEFT:
declare @c int = 0
while @c < 5
begin
SELECT *
FROM (
SELECT ABS(CONVERT(INT, CONVERT(BINARY(4), NEWID()))) % 5 AS RNDIDX
FROM (
SELECT 1 AS ID
) ROWSRC
) SUBQ
LEFT JOIN (
SELECT 0 AS VAL
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) NUM ON SUBQ.RNDIDX = NUM.VAL
set @c = @c + 1
end
Выполняем — все стало работать правильно (!) — проверерьте плз сами, скриншота для правильной работы я не делал. Заметьте, что поскольку для любого значения RNDIDX из диапазона [0..4], которое способно выдать сабквери SUBQ, всегда есть значение VAL из сабквери NUM, то с точки зрения логики результат LEFT и INNER JOIN должен быть одинаков. Однако по факту это не так!
Еще один тест — возвращаем INNER, но добавляем TOP / ORDER BY в первый сабквери. Зачем — об этом позже, давайте просто попробуем:
declare @c int = 0
while @c < 5
begin
SELECT *
FROM (
SELECT TOP 1 ABS(CONVERT(INT, CONVERT(BINARY(4), NEWID()))) % 5 AS RNDIDX
FROM (
SELECT 1 AS ID
) ROWSRC
ORDER BY RNDIDX
) SUBQ
INNER JOIN (
SELECT 0 AS VAL
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) NUM ON SUBQ.RNDIDX = NUM.VAL
set @c = @c + 1
end
Все опять работает правильно! Мистика!
Погуглив, выясняем, что с подобным поведением периодически сталкиваются SQL-разработчики со всего мира — примеры здесь, или здесь
Люди предполагают, что материализация subquery помогает. Действительно, если переписать пример, выбрав сначала записи в явном виде во временную таблицу, а затем только поджойнив, все работает нормально. Почему же на нормальную работу влияет замена INNER на LEFT, или добавление TOP / ORDER BY там, где это не нужно? Все потому же — в одном случае присутствует материализация результатов subquery, в другом — нет. Нагляднее разницу может показать анализ плана более развернутого случая, например вот этого:
DECLARE @B TABLE (VAL INT)
INSERT INTO @B
VALUES (0), (1), (2), (3), (4)
SELECT *
FROM (
SELECT ABS(CONVERT(INT, CONVERT(BINARY(4), NEWID()))) % 5 AS RNDIDX
FROM @B
) SUBQ
INNER JOIN @B B ON SUBQ.RNDIDX = B.VAL
Смотрим естественно, только выборку (query 2), заполнение таблицы @B нам ни к чему:
Мы видим, что запрос сращивает два потока строк до вычисления значения колонки, зависящей от newID(). Это может происходить потому, что SQL engine считает, что значение, возвращаемое newID(), хоть и non-deterministic, но не изменяется в течение всего батча. Однако, это не так — и скорее всего поэтому запрос работает неправильно. Теперь меняем INNER на LEFT, и смотрим план:
Ага, LEFT JOIN заставил SQL engine выполнить Compute Scalar перед объединением потоков, поэтому наш запрос стал работать правильно.
И наконец, проверим версию с добавлением TOP / ORDER BY:
Собственно, диагноз ясен. MS SQL не учитывает особенности newID(), и соответственно, неправильно строит планы, полагаясь на константное значение, возвращаемое функцией в скоупе батча. На эту особенность есть воркэраунд — заставлять SQL engine любыми способами материализовать выборку, перед тем как ее использовать в зависимых запросах. Каким способом вы будете материализовать — дело ваше, однако лучше всего, наверное, использовать табличные переменные, особенно если размер подвыборки невелик. Иначе результат, мягко говоря, не 100% гарантирован; кроме того, нет никакой гарантии, что однажды вы сами, или кто-нибудь другой не отревьюит код, выкинув «ненужные» TOP / ORDER BY или мудро заменив LEFT на INNER.
Собственно, все. Удачного SQL-программирования!
Случайная выборка из базы данных
Вы здесь:
Главная — MySQL — SQL — Случайная выборка из базы данных
Очень часто в работе программиста требуется вывести что-то случайное, чтобы это постоянно менялось от запуска к запуску. Например, вывести случайную статью, вывести случайную цитату, вывести случайные комментарии и многое другое. В этой статье мы с Вами разберём случайную выборку из базы данных.
В основе лежит команда сортировки (ORDER), и мы можем сделать так, чтобы сортировка была случайной. Это создаёт видимость случайной выборки. Вот пример запроса, который извлекает случайные записи:
SELECT * FROM `table` ORDER BY RAND()
Такой запрос вытащит все записи из таблицы и перемешает их случайным образом. На практике это нужно редко. Гораздо чаще нужно выводить именно определённое число записей:
SELECT * FROM `table` ORDER BY RAND() LIMIT 5
И данный запрос уже имеет практическую пользу, так как он позволяет вывести 5 случайных записей. Можно так вывести, например, 5 случайных изображений на страницу.
Очень часто требуется вытащить не просто случайные записи, но чтобы они удовлетворяли какому-либо условию:
SELECT * FROM `table` WHERE `id` > 5 ORDER BY RAND() LIMIT 5
Данный запрос вытащит 5 случайных записей, у которых id больше 5. Вот так делается случайная выборка из базы данных.
-
Создано 20.05.2013 10:36:36 -
Михаил Русаков
Предыдущая статья Следующая статья
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
-
Кнопка:
<a href=»https://myrusakov.ru» target=»_blank»><img src=»https://myrusakov.ru/images/button.gif» alt=»Как создать свой сайт» /></a>Она выглядит вот так:
-
Текстовая ссылка:
<a href=»https://myrusakov.ru» target=»_blank»>Как создать свой сайт</a>Она выглядит вот так: Как создать свой сайт
- BB-код ссылки для форумов (например, можете поставить её в подписи):
[URL=»https://myrusakov.ru»]Как создать свой сайт[/URL]
MySQL. Выбор случайных строк в один запрос / Habr
Что имеем?
Есть слабенький ноутбук, таблица на несколько миллионов строк и нужно выбирать разное количество случайных строк в одном запросе. Дальнейшие выборки нас не интересуют.
Таблица(test) имеет следующую структуру:
- — pk_id ( первичный ключ )
- — id ( поле заполненное разными числами )
- — value ( поле заполненной с помощью rand() )
Первичный ключ не имеет дыр и начинается с 1.
Способы получения
ORDER BY rand + LIMIT
Получение одной строки:
SELECT pk_id FROM test ORDER BY rand() LIMIT 1
Среднее время выполнения в MySQL — 6.150 секундПопробуем взять 100 записей
SELECT pk_id FROM test ORDER BY rand() LIMIT 100
Среднее время выполнения 6.170-6.180 секунды
То есть разница во времени между получением 1 и 100 случайных строк не существенна.COUNT * rand()
Получение одной строки:
SELECT t.pk_id FROM test as t, (SELECT ROUND(COUNT(pk_id)*rand()) as rnd FROM test LIMIT 1) t WHERE t.pk_id = rnd
С помощьюROUND(COUNT(pk_id)*rand())
получаем случайное число от 0 до количества строк в таблице.
Далее нашему случайному числу присваиваем алиас «rnd» и используем в WHERE для эквивалентного сравнения с pk_id.
Среднее время выполнения — 1.04 секунды
Далее нужно немного изменить данный запрос, что бы можно было вытягивать несколько строк.
Добавим еще несколько получаемых полей в наш подзапрос и изменим проверку в WHERE с «=» на INSELECT t.pk_id FROM test as t, (SELECT ROUND(COUNT(pk_id)*rand()) as rnd, ROUND(COUNT(pk_id)*rand()) as rnd2, ROUND(COUNT(pk_id)*rand()) as rnd3 FROM test LIMIT 1) t WHERE t.pk_id IN (rnd,rnd2,rnd3)
Среднее время выполнения — 1.163 секунды.
При увеличении количества получаемых строк заметно увеличивается время выполнения запроса.
Про 100 строк даже страшно подумать 🙂INFORMATION_SCHEMA + LIMIT
Получение одной строки:
SELECT t.pk_id FROM test as t, (SELECT ROUND((SELECT table_rows as tr FROM information_schema.tables WHERE table_name = 'test') *rand()) as rnd FROM test LIMIT 1) tmp WHERE t.pk_id = rnd
С помощью подподзапроса получаем количество строк в таблице ‘test’, не используя агрегатную функцию COUNT и дальнейшее сравнение происходит как в способе 2.
Среднее время выполнения — 0.042 секунды
Минимально замеченное время выполнения — 0.003 секунды.
Попробуем получить 100 строк:SELECT t.pk_id FROM test as t, (SELECT ROUND((SELECT table_rows as tr FROM information_schema.tables WHERE table_name = 'test') *rand()) as rnd FROM test LIMIT 100) tmp WHERE t.pk_id in (rnd) ORDER BY pk_id
Меняем в WHERE «=» на IN и изменяем лимит возвращаемых строк подзапросом на 100.
Среднее время выполнения — 0.047 секунды
Время на получения 1000 записей — 0.053 секунды
Время на получение 10000 записей ~ 0.21 cекунды
И напоследок 100 000 записей берем за 1.9 секунды
Минус данного подхода в том, что в получаемом количество строк из INFORMATION_SCHEMA немного больше, чем COUNT(*) и по этому при возврате 100 000 строк теряется 7-8 строк. На 1-100 такого практически нету(Чем больше таблица, тем меньше шанс). Но всегда можно взять на 1-2 строки больше, для перестраховки 🙂MAX * rand()
Получение одной строки:SELECT t.pk_id FROM test as t, (SELECT ROUND((SELECT MAX(pk_id) FROM test) *rand()) as rnd FROM test LIMIT 1) tmp WHERE t.pk_id = rnd
Среднее время выполнения — 0.001 секунды
Получение 100 строк:SELECT t.pk_id FROM test as t, (SELECT ROUND((SELECT MAX(pk_id) FROM test) *rand()) as rnd FROM test LIMIT 100) tmp WHERE t.pk_id in (rnd) ORDER BY pk_id
Среднее время выполнение — 0.003 секундыСамый быстрый способ, относительно предыдущих.
Выводы
- Первый способ хороший тем, что в любом случае вернет вам случайную строку, независимо от дыр в полях и их начального значения, но самый медленный
- Второй способ намного лучше подойдет в таблицах, где нету дыр. Работает в 6 раз быстрее, чем первый способ (на возврате одной строки).
- Третий способ можно использовать на свой страх и риск(который очень уж незначительный), потому что можно потерять строку(строки) при значение rand() максимально приближенного к 1. Скорость возврата одной строки, по сравнению с первым способом, отличается в 150 раз.
Если уж вернулось не 100 строк, а 99, то можно еще раз послать запрос на сервер. - Четвертый способ самый быстрый и в 6000 раз быстрее ORDER BY rand()
UPD: В случае дыр в таблице, при возврате одной строки вторым и третьим способом можно делать не эквивалентную проверку а >= и добавить LIMIT 1. Тогда значение будет возвращено, даже если оно попало в «дырку»
Спасибо xel за это замечание.
UPD2: Добавлен 4 способ получение. Спасибо smagen за идею.
Как генерировать случайное число для каждой строки в TSQL Select?
посмотри SQL Server-набор случайных чисел на основе, который имеет очень подробное объяснение.
подводя итог, следующий код генерирует случайное число от 0 до 13 включительно с нормализованным распределением:
ABS(CHECKSUM(NewId())) % 14
изменить свой выбор, просто измените число в конце выражения. Будьте очень осторожны, если вам нужен диапазон, который включает как положительные, так и отрицательные числа. Если вы сделаете это неправильно, можно дважды пересчитать число 0.
небольшое предупреждение для математических орехов в комнате: в этом коде очень небольшое смещение. CHECKSUM()
результаты в числах, которые одинаковы во всем диапазоне типа данных sql Int или, по крайней мере, так близко, как может показать мое (редактор) тестирование. Однако будет некоторое смещение, когда CHECKSUM() создает число в самом верхнем конце этого диапазона. Каждый раз, когда вы получаете число между максимально возможным целым числом и последним точным кратным размеру желаемого диапазона (14 в этом случае) перед этим максимальным целым числом эти результаты предпочтительнее остальной части диапазона, которая не может быть получена из последнего кратного 14.
в качестве примера представьте, что весь диапазон типа Int составляет всего 19. 19-это максимальное целое число, которое вы можете провести. Когда контрольная сумма() приводит к 14-19, они соответствуют результатам 0-5. Эти цифры будут сильно предпочтительнее 6-13, потому что контрольная сумма () в два раза чаще генерирует их. Это легче продемонстрировать визуально. Ниже приведен весь возможный набор результатов для нашего мнимого целого диапазона:
Checksum Integer: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Range Result: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 0 1 2 3 4 5
вы можете видеть здесь, что есть больше шансов произвести некоторые числа, чем другие: смещение. К счастью, фактический диапазон типа Int много больше… настолько, что в большинстве случаев предубеждение почти незаметно. Тем не менее, это то, что нужно знать, если вы когда-нибудь обнаружите, что делаете это для серьезного кода безопасности.
Выбор случайных записей (SQL) — Виталий Скальный
Похоже что в спецификациях SQL ничего нет про выборку случайных строк из таблицы. Тем не менее большинство движков баз данных поддерживает такую возможность, правда каждый по своему. Идея такая — используется сортировка не по полю, а по некоторому случайному числу, сгенерированному для каждой строки таблицы. Если взять первые n строк такой выборки, то они и будут содержать n случайных строк таблицы. Вот примеры SQL запросов:
MySql:
SELECT column FROM table
ORDER BY RAND() LIMIT 1
| SELECT column FROM table ORDER BY RAND() LIMIT 1 |
PostgreSQL:
SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1
| SELECT column FROM table ORDER BY RANDOM() LIMIT 1 |
Microsoft SQL Server:
SELECT TOP 1 column FROM table
ORDER BY NEWID()
| SELECT TOP 1 column FROM table ORDER BY NEWID() |
IBM DB2:
SELECT column, RAND() IDX
FROM table
ORDER BY IDX FETCH FIRST 1 ROWS ONLY
| SELECT column, RAND() IDX FROM table ORDER BY IDX FETCH FIRST 1 ROWS ONLY |
Oracle:
SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1
| SELECT column FROM ( SELECT column FROM table ORDER BY dbms_random.value ) WHERE rownum = 1 |
Скопипизджено из: SQL to Select a random row from a database table.
Как сгенерировать случайные тестовые данные SQL Server с помощью T-SQL
Введение
В этой статье мы поговорим о генерации случайных значений для целей тестирования.
Однажды у меня был заказчик с программным обеспечением, которое отлично работало в демонстрации с 30 строками, но через несколько месяцев в программе было больше миллиона строк, и оно стало очень медленным. Проблема была не в SQL Server, а в приложении, которое не предназначалось для таблиц с миллионами строк.Заказчик подал иск к поставщику программного обеспечения, и для принятия решения потребовались юристы. Если бы провайдер протестировал программное обеспечение с миллионами строк, этой проблемы никогда бы не возникло.
Вот почему очень важно генерировать данные и тестировать программное обеспечение с миллионами строк. Это не всегда простая задача. В этой статье мы дадим вам несколько полезных советов по T-SQL, которые могут помочь или, по крайней мере, вдохновить вас на это. В общем, случайные данные очень полезны для целей тестирования, чтобы узнать об эффективности запросов, демонстрациях и многом другом.
В этой статье мы научим, как сгенерировать до миллиона строк случайных данных в SQL Server, включая:
- комбинации имен пользователей и фамилий
- целые числа
- действительные числа с определенным диапазоном
- пароли в SQL Server
- электронные письма
- названия стран
Требования
- SQL Server
- SQL Server Management Studio (SSMS)
- Базы данных Adventure Works 2014 Full и Adventure Works DW 2014
Начало работы
1.Создайте миллион имен и фамилий
В первом примере мы будем использовать таблицу DimCustomer из базы данных AdventureWorksDW, упомянутую в требованиях. Эта таблица содержит 18 000 строк. Мы будем использовать перекрестное соединение, чтобы сгенерировать все возможные комбинации имен и фамилий. С помощью перекрестного соединения вы можете создать для своих тестов общую комбинацию из 341 658 256 пользователей. В следующем примере показано, как создать комбинацию из 1 миллиона имен пользователей и фамилий:
se ИСПОЛЬЗУЙТЕ [AdventureWorksDW2014] GO —Измените 1000000 на номер по вашему выбору в соответствии с вашими потребностями SELECT TOP 1000000 c1.[FirstName], c2. [LastName] FROM [dbo]. [DimCustomer] c1 CROSS JOIN DimCustomer c2 |
В примере будет отображаться 1 000 000 строк имен и фамилий:
Рисунок 1. Создание всех возможных комбинаций между именем и фамилией
Если вы хотите сгенерировать 34 миллиона строк, вам нужно заменить эту строку:
С этим:
Запрос генерирует декартово произведение со всеми комбинациями, а TOP ограничивает количество строк.
2. Генерация случайных целочисленных значений
В следующем примере показано, как создать таблицу из 1000 строк со случайными значениями от 1 до 100. Мы будем использовать функцию RAND для создания случайных значений и CHECKSUM (NEWID ()) для генерации различных значений. Мы используем приведение для преобразования значений из реальных в целые числа:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 18 19 | со случайными значениями как ( выберите 1 идентификатор, CAST (RAND (CHECKSUM (NEWID ())) * 100 как int) randomnumber — выберите 1 идентификатор, RAND (CHECKSUM (NEWID ())) * 100 randomnumber union all select id + 1, CAST (RAND (CHECKSUM (NEWID ())) * 100 as int) randomnumber —select id + 1, RAND (CHECKSUM (NEWID ())) * 100 randomnumber из randowvalues где id <1000 ) select * from randowvalues OPTION (MAXRECURSION 0) |
Код покажет 100 значений от 1 до 100:
Рисунок 2.Целочисленные случайные значения, созданные в SQL Server
Если вы хотите сгенерировать 10000 значений, измените эту строку:
id <1000
С этим:
id <10000
Если вы хотите сгенерировать значения от 1 до 10000, измените эти строки:
выберите 1 id, CAST (RAND (CHECKSUM (NEWID ())) * 10000 как int) случайное число объедините все выберите id + 1, CAST (RAND (CHECKSUM (NEWID ())) * 10000 как int) randomnumber из randowvalues |
Если вы хотите генерировать реальные значения вместо целых значений, используйте эти строки, замените эти строки кода, отображаемого ранее:
выберите 1 id, CAST (RAND (CHECKSUM (NEWID ())) * 10000 как int) случайное число объедините все выберите id + 1, CAST (RAND (CHECKSUM (NEWID ())) * 10000 как int) randomnumber из randowvalues |
И используйте эти:
select 1 id, RAND (CHECKSUM (NEWID ())) * 10000 случайное число объединение всех select id + 1, RAND (CHECKSUM (NEWID ())) * 10000 случайное число из случайных значений |
Запрос покажет действительные числа от 0 до 100
3.Случайные действительные числа с определенным диапазоном
Другой типичный запрос — предоставить случайные значения с конкретными диапазонами. В следующем примере показан диапазон температур в ° F (я действительно предпочитаю метрическую систему, но на этот раз сделаю исключение).
Человеческое тело имеет следующие колебания температуры: от 95 до 105,8 ° F (нормальная температура составляет от 97,7 до 99,5 ° F, более высокие значения означают лихорадку, гипертермию, а более низкие значения — гипотермия).
В этом примере мы сгенерируем значения от 95 до 105.8 ° F:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 18 19 20 | со случайными значениями как ( —10.8 — разница между 105,8 минус 95 select 1 id, CAST (RAND (CHECKSUM (NEWID ())) * 10.8 as real) +95 как randomnumber union all select id + 1, CAST (RAND (КОНТРОЛЬНАЯ СУММА (NEWID ())) * 10.8 как действительное) +95 как случайное число из случайных значений , где id <100 ) выберите * из случайных значений ОПЦИЯ (0) |
Результатом оператора T-SQL будут значения от 95 до 105.8 ° F:
Рисунок 3. Случайные действительные числа от 0 до 100
Если вам нужны действительные числа от 6 до 10, измените эти строки кода:
select 1 id, CAST (RAND (CHECKSUM (NEWID ())) * 10,8 как действительное) +95 как случайное число объединение всех select id + 1, CAST (RAND (CHECKSUM (NEWID ())) * 10,8 как действительное) +95 как случайное число |
С этими:
выберите 1 id, CAST (RAND (CHECKSUM (NEWID ())) * 4 как действительное) +6 как случайное число объедините все выберите id + 1, CAST (RAND (CHECKSUM (NEWID ())) * 4 как реальное число) +6 как случайное число |
Где 6 — минимальное значение, а 4 — разница между 10 и 6.
4. Случайные пароли в SQL Server
Другой распространенный запрос — сгенерировать пароли. Этот пример используется для начальных паролей, которые впоследствии будут изменены пользователем или когда пользователь забудет пароль.
В следующем примере будет сгенерировано 100 паролей:
с randowvalues как ( выберите 1 идентификатор, CONVERT (varchar (20), CRYPT_GEN_RANDOM (10)) как mypassword объединить все выберите id + 1, CONVERT (varchar (20), CRYPT_GEN 10)) как mypassword из randowvalues , где id <100 ) выберите * из randowvalues OPTION (MAXRECURSION 0) |
Значения, отображаемые операторами T-SQL, следующие:
Рисунок 4.Случайные пароли
Мы используем функцию CRYPT_GEN_RANDOM для генерации паролей, а затем преобразуем их в varchar. Функция возвращает шестнадцатеричные значения, и мы конвертируем их в символы.
5. Генерация случайных писем
В следующем примере будет сгенерировано несколько паролей. Мы будем использовать имена и фамилии из примера 1 таблицы DimCustomer для генерации случайных поддельных электронных писем в SQL Server. Если у нас есть, например, Заказчик по имени Джон Смит, мы сгенерируем электронное письмо, которое может быть jsmith @ gmail.com или используйте учетную запись Hotmail или Yahoo. Давайте посмотрим на код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 18 19 20 21 22 23 24 25 26 27 28 | ИСПОЛЬЗОВАНИЕ [AdventureWorksDW2014] GO со случайным как ( SELECT TOP 10000 c1.[FirstName], c2. [LastName], CAST (RAND (CHECKSUM (NEWID ())) * 3 as int) randomemail FROM [dbo]. [DimCustomer] c1 CROSS JOIN DimCustomer ) выберите Имя, Фамилия, адрес электронной почты = CASE когда randommail = 0, затем ниже (слева (FirstName, 1) + [LastName]) + ‘@ hotmail.com’ , если randommail = 1, затем ниже (слева (FirstName, 1) + [LastName]) + ‘@ gmail.com ‘ else ниже (слева (FirstName, 1) + [LastName]) +’ @ yahoo.com ‘ END из случайного |
Код будет извлекать первую букву имени и объединять с фамилией и случайным образом объединять Hotmail, gmail или yahoo:
Рисунок 5. Случайные электронные письма
6. Генерация названий стран случайным образом
Этот последний пример покажет, как генерировать случайные названия стран.Мы будем использовать таблицу Person.CounryRegion из базы данных adventureworks и добавим идентификатор с помощью функции Row_number:
SELECT ROW_NUMBER () OVER (ORDER BY Name) AS id, [Name] FROM [AdventureWorks2016CTP3]. [Person]. [CountryRegion] |
В этой таблице представлены 238 стран:
Рисунок 6.Список стран в таблице Person.CountryRegion проекта adventureworks
Мы будем использовать список случайных чисел из второго примера для генерации значений от 1 до 238 (238 — общее количество стран), мы будем использовать внутреннее соединение, чтобы объединить случайные числа со странами и сгенерировать названия стран случайным образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 18 19 20 21 22 23 24 25 26 27 28 29 31 | ; со странами как ( — Создайте идентификатор страны и название страны.Countryid будет использоваться для — соединения со случайными числами SELECT ROW_NUMBER () OVER (ORDER BY Name) AS countryid, [Name] FROM [AdventureWorks2016CTP3]. [Person]. [CountryRegion] ), — Создайте 1000 случайных чисел от 1 до 238 randowvalues как ( выберите 1 id, CAST (RAND (CHECKSUM (NEWID ())) * 238 как int) randomnumber union все select id + 1, CAST (RAND (CHECKSUM (NEWID ())) * 238 as int) randomnumber from randowvalues , где id <1000 ) — Присоединение стран со случайными числами для генерации названий стран случайным образом выберите случайное число, c.Имя из randowvalues r страны внутреннего присоединения c на r.randomnumber = c.countryid заказать по идентификатору OPTION (MAXRECURSION 0) |
Операторы T-SQL случайным образом сгенерируют список стран:
Рисунок 7. Список стран, сгенерированный случайным образом
Выводы
Сгенерировать случайные значения для тестирования может быть сложно.Однако эта статья может быть полезна, чтобы вдохновить вас на создание собственных данных. Иногда мы можем использовать существующие таблицы для генерации большего количества значений. Иногда мы можем создавать данные с нуля. В этом примере мы покажем, как создавать данные с помощью функции Random.
В этой статье мы сгенерировали миллионы имен и фамилий, случайных целочисленных значений, реальных значений с определенными диапазонами, случайных паролей, случайных электронных писем с использованием имени и фамилии и случайных названий стран.
Даниэль Кальбимонте — самый ценный специалист Microsoft, сертифицированный инструктор Microsoft и сертифицированный ИТ-специалист Microsoft по SQL Server.Он является опытным автором SSIS, преподавателем ИТ-академий и имеет более 13 лет опыта работы с различными базами данных.
Он работал в правительстве, нефтяных компаниях, на веб-сайтах, в журналах и университетах по всему миру. Даниэль также регулярно выступает на конференциях и в блогах по SQL Server. Он пишет учебные материалы по SQL Server для сертификационных экзаменов.
Он также помогает с переводом статей по SQLShack на испанский
Просмотреть все сообщения Даниэля Кальбимонте
Последние сообщения Даниэля Кальбимонте (посмотреть все)
.Сервер
sql — создание уникальных случайных чисел с использованием SQL
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
Загрузка…
- Авторизоваться
зарегистрироваться текущее сообщество
Переполнение стека
Помогите
болтать
.
sql — генерировать случайное число в диапазоне 1-10
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
Загрузка…
генерирует случайное число x цифр в sql server 2008 R2
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
Загрузка…