Nano Hash - криптовалюты, майнинг, программирование

Возможное объяснение WITH RECURSIVE Query Postgres

Я читал With Query в Postgres. И вот что меня удивляет

WITH RECURSIVE t(n) AS (
    VALUES (1)
  UNION ALL
    SELECT n+1 FROM t WHERE n < 100
)
SELECT sum(n) FROM t;

Я не могу понять, как работает оценка запроса.

  • t(n) звучит как функция с параметром. как передается значение n.

Любое понимание того, как происходит сбой рекурсивного оператора в SQL.



Ответы:


1

Это называется общим табличным выражением и представляет собой способ выражения рекурсивного запроса в SQL:

t(n) определяет имя CTE как t с одним столбцом с именем n. Это похоже на псевдоним для производной таблицы:

select ... 
from (
  ...
) as t(n);

Рекурсия начинается со значения 1 (это часть values (1)), а затем рекурсивно добавляет к нему единицу, пока не будет достигнуто 99. Таким образом, он генерирует числа от 1 до 99. Затем окончательный запрос суммирует все эти числа.

n — это имя столбца, не "переменная", и "назначение" происходит так же, как и любой поиск данных.

WITH RECURSIVE t(n) AS (
    VALUES (1) --<< this is the recursion "root"
  UNION ALL
    SELECT n+1 FROM t WHERE n < 100 --<< this is the "recursive part"
)
SELECT sum(n) FROM t;

Если вы «развернете» рекурсию (которая на самом деле является итерацией), вы получите что-то вроде этого:

select x.n + 1
from (
  select x.n + 1
  from (
    select x.n + 1
    from (
      select x.n + 1
      from (
         values (1)
      ) as x(n) 
    ) as x(n)
  ) as x(n)
) as x(n)

Подробнее в руководстве:
https://www.postgresql.org/docs/current/static/queries-with.html

17.06.2016
  • Я понимаю, что делает оператор SQL, все, что я хочу знать, как работает оценка с тех пор. например, как значение n присваивается 1 (я знаю, что оно присваивается VALUES (1), но как?) рядом с Union ALL on VALUES(1) and SELECT n+1 ... Просто это сильно отличается от того, как традиционная функция рекурсии мы пишем в высоком конце язык, например C или C++ 17.06.2016
  • Цель вопроса - понять оценку. Так что я могу быть достаточно уверенным, чтобы написать один, если это необходимо. 17.06.2016
  • @LivingColors n не является переменной. Это имя столбца. 17.06.2016
  • Evaluate the non-recursive term. For UNION (but not UNION ALL), discard duplicate rows. Include all remaining rows in the result of the recursive query, and also place them in a temporary working table. . Можете ли вы помочь мне понять, что такое рекурсивный термин в приведенном выше примере. Я не могу понять, какая часть оператора вызывает рекурсию. 17.06.2016
  • values(1) — это нерекурсивная часть (она же корень). Выбор после union all является рекурсивной частью (поскольку он ссылается/присоединяется к CTE (с именем t) 17.06.2016
  • Глядя на открытую форму, как select x.n + 1 from ( values (1) ) as x(n) добавляет столбец «2» во временную таблицу, в которой его еще нет? 10.06.2019

  • 2

    Если вы ищете, как это оценивается, рекурсия происходит в два этапа.

    1. Корень выполняется один раз.
    2. Рекурсивная часть выполняется до тех пор, пока не будут возвращены строки. Документация немного расплывчата в этом вопросе.

    Теперь, обычно в базах данных, мы думаем о «функции» иначе, чем мы думаем о них, когда занимаемся императивным программированием. В терминах базы данных лучший способ думать о функции — это «соответствие, в котором для каждого значения домена у вас есть ровно одно соответствующее значение». Так что одна из неотложных задач — перестать думать в терминах функций программирования. Даже пользовательские функции лучше рассматривать с другой точки зрения, поскольку это позволяет избежать многих потенциальных неприятностей, связанных с пересечением выполнения запроса и планировщика запросов... Таким образом, это может выглядеть как функция, но это неверно.

    Вместо этого в предложении WITH используется другая, почти обратная запись. Здесь у вас есть имя набора t, за которым следует (необязательно в этом случае) структура кортежа (n). Так что это не функция с параметром, а отношение со структурой.

    Итак, как это ломается:

    SELECT 1 as n where n < 100
    UNION ALL
    SELECT n + 1 FROM (SELECT 1 as n) where n < 100
    UNION ALL
    SELECT n + 1 FROM (SELECT n + 1 FROM (SELECT 1 as n)) where n < 100
    

    Конечно, это упрощение, потому что внутренне мы отслеживаем состояние cte и продолжаем объединяться с последней итерацией, поэтому на практике они сводятся к почти линейной сложности (в то время как приведенная выше диаграмма предполагает гораздо худшую производительность).

    Итак, на самом деле вы получаете что-то вроде:

     SELECT 1 as n where 1 < 100
     UNION ALL
     SELECT 1 + 1 as n where 1 + 1 < 100
     UNION ALL
     SELECT 2 + 1 AS n WHERE 2 + 1 < 100
     ...
    

    По сути, предыдущие значения сохраняются.

    17.06.2016
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..