Ваш вопрос довольно длинный и бессвязный - ни одного вопроса. Но это интересно, и я кое-что узнал.
Это утверждение не соответствует действительности:
SQL Server назначает случайное начальное число для функции RAND (): при использовании в
SELECT, он высевается только один раз, а не для каждой строки.
SQL Server имеет концепцию постоянных функций во время выполнения. Это функции, которые извлекаются из скомпилированного запроса и выполняются один раз для выражения в начале запроса. Наиболее яркими примерами являются getdate()
(и соответствующие функции даты / времени) и rand()
.
Вы можете легко увидеть это, если запустите:
select rand(), rand()
from (values (1), (2), (3)) v(x);
Каждый столбец имеет одинаковые значения, но значения между столбцами различны.
Большинство баз данных, включая SQLite, имеют более интуитивно понятную интерпретацию rand()
/ random()
. (Как личное примечание, «случайная» функция, которая возвращает одно и то же значение в каждой строке, очень нелогична.) Каждый раз, когда она вызывается, вы получаете другое значение. Для SQL Server вы обычно используете выражение, использующее newid()
:
select rand(), rand(), rand(checksum(newid()))
from (values (1), (2), (3)) v(x);
Что касается вашего второго вопроса, кажется , что SQLite материализует рекурсивные CTE. Так что это то, что вы хотите:
WITH tbl1(n) AS (
SELECT 1 UNION ALL SELECT 2
),
tbl2(n, r) AS (
SELECT n, RANDOM()
FROM tbl1
union all
select *
from tbl2
where 1=0
)
SELECT *
FROM tbl2 t1 CROSS JOIN tbl2 t2;
Я не видел документации, что это так, поэтому используйте на свой страх и риск. Здесь - DB-Fiddle.
И, к сведению, похоже, что это работает и в SQL Server. Я только что чему-то научился!
EDIT:
Как предлагается в комментарии, материализация не всегда может происходить. Похоже, это относится к двум ссылкам на одном уровне:
WITH tbl1(n) AS (
SELECT 1 UNION ALL SELECT 2),
tbl2(n, r) AS (
SELECT n, RANDOM()
FROM tbl1
union all
select *
from tbl2
where 1=0
)
SELECT t2a.r, count(*)
FROM tbl2 t2a left JOIN
tbl2 t2b
on t2a.r = t2b.r
GROUP BY t2a.r;