#mysql #sql #logic #presto
#mysql #sql #Логические #presto
Вопрос:
У меня есть таблица, в которой каждый идентификатор кода ссылается на другой столбец в той же таблице, ниже приведен сценарий
Table: Code
OldCode NewCode
A B
B C
C D
D E
Я хочу запросить приведенную выше таблицу, где для OldCode
= A результирующий код должен быть NewCode
= E
т.е.: A->B
, B->C
, C->D
, D->E
Я не мог придумать логику в запросе для ее достижения, но мы могли бы сделать это через dataframe
, но я хочу, чтобы di через запрос.
Я пытался с CTE, но я не могу понять рекурсивную концепцию CTE для ее достижения.
Комментарии:
1. Какова ваша фактическая база данных? Здесь вы использовали несколько тегов базы данных.
2. Мы работаем на Presto, данные, которые мы вставляем в presto, взяты из SQL, поэтому мы можем сделать это в любом месте, если это sql, я могу создать другую таблицу и вставить последний код в таблицу для запроса. @TimBiegeleisen
Ответ №1:
Здесь вы можете использовать рекурсивный CTE:
WITH RECURSIVE cte(n) AS (
SELECT OldCode, NewCode, 1 AS lvl FROM yourTable WHERE OldCode = 'A'
UNION ALL
SELECT t1.OldCode, t1.NewCode, n 1
FROM yourTable t1
INNER JOIN cte t2 ON t2.NewCode = t1.OldCode
)
SELECT NewCode
FROM cte
ORDER BY lvl DESC
LIMIT 1;
Логика здесь заключается в том, чтобы объединить все уровни вместе на рекурсивном шаге CTE (который показан ниже UNION ALL
). Мы также вычисляем уровень для каждого соединения, начиная с 1 в базовом случае. Затем, чтобы получить NewCode
то, что мы хотим, мы просто берем запись с самым высоким значением уровня.
Комментарии:
1. Спасибо за решение @tim, если я хочу запросить более одной записи, я хочу запускать этот CTE каждый раз? это займет больше времени и ресурсов?
2. Возможно, существует способ обрабатывать несколько путей одновременно (однако я об этом не знаю). Если вам нужно выполнить несколько раз, вы можете поместить эту логику в proc. Кроме того, для повышения производительности мы могли бы рассмотреть возможность соответствующей индексации вашей таблицы.