Это создает неявное 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 см. Также мой ответ здесь
,
быть перекрестным соединением, так как это просто декартово произведение, и здесь нет никакого сравнения. Можете ли вы просто ответить на еще 1 вопрос ПОЖАЛУЙСТА? чтоt(x)
в(values(1)) AS t(x)
???to_tsquery()
возвращает значение, а не строку . И только потому , что функция определенаSTABLE
, это не означает , планировщик запросов будет избежать повторной оценки. Это может .В руководстве есть подробное объяснение запятой в
FROM
списке в главе « Выражения таблиц» :Тот факт, что ссылки на разделенные запятыми таблицы были определены в более ранней версии стандарта SQL, чем явный
JOIN
синтаксис, не делает запятую неправильной или устаревшей. Используйте явный синтаксис соединения, где это технически необходимо (см. Ниже) или где это делает текст запроса более понятным.Руководство снова:
Но «эквивалент» не означает идентичный . Существует небольшая разница, как отмечает руководство :
Этот связанный вопрос демонстрирует актуальность различия:
По сути, ваше наблюдение совершенно верно:
Любая функция может быть использована в качестве «табличной функции» в
FROM
списке. И параметры функции могут ссылаться на столбцы из всех таблиц слева от функции, потому что обозначение:действительно эквивалентно:
Пособие по БОЛЬШИМУ запросам:
Жирный акцент мой.
Ключевое слово
AS
является обязательным шума перед тем таблицы псевдонимов (в отличие от псевдонимов столбцов , где рекомендуется не пропустить ,AS
чтобы избежать возможных неоднозначностей). Связанный ответ с более:источник