Что [ОТ x, y] означает в Postgres?


12

Я только начинаю с Postgres. Читая этот документ, я наткнулся на этот запрос:

SELECT title, ts_rank_cd(textsearch, query) AS rank
FROM apod, to_tsquery('neutrino|(dark & matter)') query
WHERE query @@ textsearch
ORDER BY rank DESC
LIMIT 10;

Я могу понять все , что в этом запросе, за исключением того, для этого: FROM apod, ....

Что это ,значит? Я привык к объединениям, но не к нескольким FROMоператорам, разделенным запятой.

Я искал в сети безрезультатно. Посмотрев на него и подумав, мне кажется, что он объявляет переменную с именем query, поэтому он может использовать ее несколько раз. Но если это правда, с чем это связано FROM?

Ответы:


10

Это создает неявное CROSS JOIN. Это синтаксис SQL-89.

Здесь я использую values(1)и values(2)для создания псевдо-таблиц (таблиц значений) только для примеров. То, что после них t(x)и g(y)называется FROM-Aliases, символ внутри скобки является псевдонимом для столбца ( xи yсоответственно). Вы можете также легко создать таблицу для проверки этого.

SELECT *
FROM (values(1)) AS t(x), (values(2)) AS g(y)

Вот как бы вы написали это сейчас.

SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(2)) AS g(y);

Оттуда вы можете сделать это неявным INNER JOIN, добавив условное выражение.

SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(1)) AS g(z)
WHERE x = z;

Или явный и более новый INNER JOINсинтаксис,

SELECT *
FROM (values(1)) AS t(x)
INNER JOIN (values(1)) AS g(z)
  ON ( x = z );

Так в вашем примере ..

FROM apod, to_tsquery('neutrino|(dark & matter)') query

Это по сути такой же, как новый синтаксис,

FROM apod
CROSS JOIN to_tsquery('neutrino|(dark & matter)') AS query

что на самом деле то же самое, в этом случае, потому что to_tsquery()возвращает строку, а не набор как,

SELECT title, ts_rank_cd(
  textsearch,
  to_tsquery('neutrino|(dark & matter)')
) AS rank
FROM apod
WHERE to_tsquery('neutrino|(dark & matter)') @@ textsearch
ORDER BY rank DESC
LIMIT 10;

Тем не менее, вышеупомянутое может потенциально привести to_tsquery('neutrino|(dark & matter)')к тому, что произойдет дважды, но в этом случае это не - to_tsqueryпомечается как STABLE (проверено с помощью \dfS+ to_tsquery).

STABLEуказывает на то, что функция не может изменить базу данных и что при сканировании одной таблицы она будет последовательно возвращать один и тот же результат для тех же значений аргумента, но что ее результат может изменяться в разных операторах SQL. Это подходящий выбор для функций, результаты которых зависят от поиска в базе данных, переменных параметров (таких как текущий часовой пояс) и т. Д. (Это не подходит для триггеров AFTER, которые хотят запрашивать строки, измененные текущей командой.) Также обратите внимание, что Семейство функций current_timestamp квалифицируется как стабильное, поскольку их значения не изменяются в транзакции.

Для более полного сравнения различий между SQL-89 и SQL-92 см. Также мой ответ здесь


Большое спасибо. Я только начинаю с SQL. Имеет смысл ,быть перекрестным соединением, так как это просто декартово произведение, и здесь нет никакого сравнения. Можете ли вы просто ответить на еще 1 вопрос ПОЖАЛУЙСТА? что t(x)в (values(1)) AS t(x)???
Андреперпена

@andrerpena обновлен.
Эван Кэрролл

1
Ты самый лучший. Кристально чистое объяснение. Благодаря тонну.
Андреперпена

Никогда не слышал термин «ОТ псевдонима» для псевдонима таблицы . to_tsquery()возвращает значение, а не строку . И только потому , что функция определена STABLE, это не означает , планировщик запросов будет избежать повторной оценки. Это может .
Эрвин Брандштеттер,

12

В руководстве есть подробное объяснение запятой в FROMсписке в главе « Выражения таблиц» :

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

FROM table_reference [, table_reference [, ...]]

Ссылка на таблицу может быть именем таблицы (возможно, дополненной схемой) или производной таблицей, такой как подзапрос, JOINконструкция или их сложные комбинации. Если в FROMпредложении указано более одной ссылки на таблицу , таблицы соединяются перекрестно (то есть формируется декартово произведение их строк; см. Ниже).

Тот факт, что ссылки на разделенные запятыми таблицы были определены в более ранней версии стандарта SQL, чем явный JOINсинтаксис, не делает запятую неправильной или устаревшей. Используйте явный синтаксис соединения, где это технически необходимо (см. Ниже) или где это делает текст запроса более понятным.

Руководство снова:

FROM T1 CROSS JOIN T2эквивалентно FROM T1 INNER JOIN T2 ON TRUE (см. ниже). Это также эквивалентно FROM T1, T2.

Но «эквивалент» не означает идентичный . Существует небольшая разница, как отмечает руководство :

Примечание.
Эта последняя эквивалентность не выполняется точно, когда появляется более двух таблиц, поскольку JOINсвязывается более тесно, чем запятая. Например, FROM T1 CROSS JOIN T2 INNER JOIN T3 ON conditionэто не то же самое, FROM T1, T2 INNER JOIN T3 ON conditionчто conditionссылка can T1в первом случае, но не во втором.

Этот связанный вопрос демонстрирует актуальность различия:

По сути, ваше наблюдение совершенно верно:

мне кажется, что она объявляет переменную с именем query, поэтому она может использовать ее несколько раз.

Любая функция может быть использована в качестве «табличной функции» в FROMсписке. И параметры функции могут ссылаться на столбцы из всех таблиц слева от функции, потому что обозначение:

FROM apod, to_tsquery('neutrino|(dark & matter)') query

действительно эквивалентно:

FROM apod CROSS JOIN LATERAL to_tsquery('neutrino|(dark & matter)') AS query

Пособие по БОЛЬШИМУ запросам:

Табличным функциям, появляющимся в, FROMтакже может предшествовать ключевое слово LATERAL, но для функций ключевое слово является необязательным ; аргументы функции могут содержать ссылки на столбцы, предоставленные предшествующими элементами FROM в любом случае.

Жирный акцент мой.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.