Используйте представления и табличные функции как таблицы узлов или ребер в предложениях соответствия

Мне нравится использовать табличные функции в MATCH пункты так же, как это возможно с Node таблицы Есть ли способ добиться этого?

Потребность в табличных функциях

Возможны различные варианты использования табличных функций или представлений в качестве Node таблицы Например, мое следующее.
я имею Node таблицы, содержащие NVarChar(max) поля, которые я хотел бы найти для буквального текста. Мне нужен только поиск по равенству и полнотекстовый поиск, поэтому я решил использовать индекс для значения хеш-функции текстового поля. Как предложил Remus Rusanu в своем ответе на SQL-сервер, стоит ли индексировать большие строковые ключи? и https://www.brentozar.com/archive/2013/05/indexing-wide-keys-in-sql-server/. Табличная функция обрабатывает, используя CHECKSUM индекс; см. сообщение 207 Неверное имя столбца $node_id для псевдостолбца во встроенной табличной функции.

Пример определения данных

CREATE TABLE [Tags](
    [tag] NVarChar(max),
    [tagHash] AS CHECKSUM([Tag]) PERSISTED NOT NULL
) as Node;

CREATE TABLE [Sites](
    [endPoint] NVarChar(max),
    [endPointHash] AS CHECKSUM([endPoint]) PERSISTED NOT NULL
) as Node;

CREATE TABLE [Links] as Edge;

CREATE INDEX [IX_TagsByName] ON [Tags]([tagHash]);

GO

CREATE FUNCTION [TagsByName](
    @tag NVarChar(max))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT
    $node_id AS [NodeId],
    [tag],
    [tagHash]
FROM [dbo].[Tags]
WHERE [tagHash] = CHECKSUM(@tag) AND
    [tag] = @tag;

[TagsByName] возвращает $node_id с псевдонимом NodeId как предложено /questions/25820397/msg-207-nevernoe-imya-stolbtsa-nodeid-dlya-psevdostolbtsa-vo-vstroennoj-tablichnoj-funktsii/25820404#25820404. Однако настоящий Node таблицы содержат еще два внутренних столбца, которые я не знаю, как экспортировать.

Желаемый запрос

Я хотел бы запросить базу данных, подобную этой:

SELECT *
FROM [TagsByName]('important') as t,
    [Sites] as s,
    [Links] as l
WHERE MATCH ([t]-([l])->[s])

Однако это приводит к ошибке 1:

Сообщение 13901, Уровень 16, Состояние 2, Линия...
Идентификатор "т" в MATCH Предложение не является таблицей узлов или псевдонимом для таблицы узлов.

Есть ли способ сделать это?


PS. Есть некоторые обходные пути, но они не выглядят так элегантно, как MATCH -query; особенно учитывая, что мой фактический запрос включает в себя сопоставление большего количества отношений и больше тестов на равенство строк. Я опубликую эти обходные пути как ответы и надеюсь, что кто-то придет с лучшей идеей.

1 Это дает очень специфическую разницу между представлениями и таблицами для разницы между представлением и таблицей в sql; что происходит только в /questions/tagged/sql-server-2017 и только при использовании SQL Graph.

3 ответа

Решение

Временное решение

Добавить Node table дважды к предложению from: один раз как таблица и один раз как функция с табличным значением и присоедините их через $node_id в предложении where:

SELECT *
FROM [TagsByName]('important') as t1,
    [Tags] as t2,
    [Sites] as s,
    [Links] as l
WHERE MATCH ([t2]-([l])->[s]) AND
    t1.[NodeId] = t2.$node_id

Влияет ли это на производительность?

Временное решение

Возврат к традиционным реляционным соединениям через JOIN пункты или FROM с <table_or_view_name> а также WHERE статьи. В запросах, которые соответствуют большему количеству отношений, последний имеет преимущество в том, что /questions/tagged/sql-server-2017-graph может MATCH на FROM <table_or_view_name> но не на FROM <table_source> JOIN <table_source>,

SELECT *
FROM [TagsByName]('important') as t
    [Sites] as s,
    [Links] as l
WHERE t.NodeId = l.$from_id AND
    l.$to_id = s.$node_id;

Временное решение

Не используйте табличную функцию, но включите ее выражение в WHERE пункт:

SELECT *
FROM [Tags] as t,
    [Sites] as s,
    [Links] as l
WHERE MATCH ([t]-([l])->[s]) AND
    [t].[tagHash] = CHECKSUM('important') AND
    [t].[tag] = 'important'

Недостаток: это легко ошибиться; например, забыв присоединиться к CHECKSUM

Другие вопросы по тегам