1

我喜欢在子句中使用表值函数,就像使用一样。有没有办法做到这一点?MATCHNode

对表值函数的需求

Node将表值函数或视图用作表可以有多种用例。例如我的如下。
我有Node包含NVarChar(max)要搜索文字文本的字段的表。我只需要相等搜索而不需要全文搜索,所以我选择在文本字段的哈希值上使用索引。正如Remus Rusanu在他对SQL server 的回答中所建议的那样——值得索引大字符串键吗?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]返回https://stackoverflow.com/a/45565410/814206建议$node_id的别名。但是,实际包含另外两个我不知道如何导出的内部列。NodeIdNode

所需查询

我想查询类似这样的数据库:

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

但是,这会导致错误1 ​​:

消息 13901,级别 16,状态 2,行 ...子句
中的标识符“t”MATCH不是节点表或节点表的别名。

我有办法做到这一点吗?


PS。有一些解决方法,但它们看起来不像MATCH-query 那样优雅;特别是考虑到我的实际查询涉及匹配更多的关系和更多的字符串相等测试。我会将这些解决方法作为答案发布,并希望有人提出更好的主意。

1 这给出了视图和表之间非常具体的区别,用于SQL 中视图和表之间的差异;这仅在中发生并且仅在使用 SQL Graph 时发生。

4

3 回答 3

0

解决方法

JOIN通过子句或FROMwith<table_or_view_name> and子句恢复到传统的关系连接WHERE。在匹配更多关系的查询中,后者具有可以MATCHonFROM <table_or_view_name>但不能 on的优势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;
于 2017-08-16T08:45:03.327 回答
0

解决方法

Node表两次添加到 from 子句:一次作为表,一次作为表值函数,并通过$node_idwhere 子句中的连接它们:

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

这会影响性能吗?

于 2017-08-16T08:50:02.930 回答
0

解决方法

不要使用表值函数,而是在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

于 2017-08-16T08:55:33.583 回答