SQL选择标记值的位置,如
我正在尝试创建一个日历服务,在该日历服务中,有一些事件,这些事件可以用可搜索的元数据进行标记 我希望能够搜索所有标签必须存在强制标签和/或任何标签存在可选标签的记录 我已经成功地创建了一个查询,当标记值与“恰好”匹配时,该查询在哪里工作。但我无法确定如何返回标记值类似于“%value%”的结果 这是我当前的实现 表和数据 质疑 我已经为它创建了一个 我的想法是使用@SearchTypeId在精确匹配搜索和相似匹配搜索之间切换 注意,我不是DBA,因此可能有更好的方法来实现这一点。我愿意听取建议 有人能提供关于如何在标签值上获得相似匹配的建议吗SQL选择标记值的位置,如,sql,sql-server-2008,Sql,Sql Server 2008,我正在尝试创建一个日历服务,在该日历服务中,有一些事件,这些事件可以用可搜索的元数据进行标记 我希望能够搜索所有标签必须存在强制标签和/或任何标签存在可选标签的记录 我已经成功地创建了一个查询,当标记值与“恰好”匹配时,该查询在哪里工作。但我无法确定如何返回标记值类似于“%value%”的结果 这是我当前的实现 表和数据 质疑 我已经为它创建了一个 我的想法是使用@SearchTypeId在精确匹配搜索和相似匹配搜索之间切换 注意,我不是DBA,因此可能有更好的方法来实现这一点。我愿意听取建议
非常感谢我认为您使用某种类型的标志/开关来更改匹配类型的想法会奏效。我使用单词而不是ID实现了它,但是如果您只是根据搜索类型切换连接条件,您应该会得到预期的匹配 小提琴: 我首先添加了一个类似于标记1的标记,并将其附加到事件2中进行测试
INSERT INTO Tags VALUES (3, 'Different Tag Name 1');
INSERT INTO EventTags VALUES (2, 3, 'Value 3');
然后我创建了搜索类型标志/开关
DECLARE @SearchType NVARCHAR(10)
SET @SearchType = 'LIKE' --other type is EXACT
因此,现在可以基于该标志切换EXISTS连接条件。我把你的不存在变成存在只是为了我的理解。下面是新的连接条件,使用强制标记块作为示例
-- Select ids with matching mandatory tags.
;WITH MandatoryTags AS
(
SELECT TagValue.value('(./value)[1]', 'nvarchar(100)') AS value,
TagValue.value('(./description)[1]', 'nvarchar(100)') AS [description]
FROM @MandatoryTagXml.nodes('/tags/tag') AS T(TagValue)
)
INSERT INTO @MandatoryIdTable
-- Records where ALL tags match EXACTLY or LIKE
SELECT E.Id [EventId], ED.Id [EventDateId]
FROM [dbo].[Events] E
INNER JOIN [dbo].[EventDates] ED ON ED.EventId = E.Id
WHERE ED.StartDate >= @StartDate
AND ED.EndDate <= @EndDate
AND ED.Archived = 0
AND EXISTS (
-- Just care about tag IDs here, not the values
SELECT T.Id
FROM MandatoryTags c JOIN Tags T
ON (
-- Toggle join type based on flag/switch
(@SearchType = 'EXACT' AND c.[description] = T.[Description])
OR
(@SearchType = 'LIKE' AND T.[Description] LIKE ('%' + c.[description] + '%'))
)
INTERSECT
SELECT T.TagId
FROM [EventTags] T
WHERE T.EventId = E.Id
)
我相信您可以在这个SQL中进行一些重新分解和优化,但这至少可以让您了解如何在需要时进行相似匹配。希望有帮助 给了我所需要的刺激,让我发现需要做什么
添加此节将获得与值相似的匹配:
JOIN EventTags ET
ON C.[Value] LIKE '%' + ET.Value + '%'
So, for example, the mandatory section becomes:
-- Select ids with matching mandatory tags.
;WITH MandatoryTags AS
(
SELECT TagValue.value('(./value)[1]', 'nvarchar(100)') AS value,
TagValue.value('(./description)[1]', 'nvarchar(100)') AS [description]
FROM @MandatoryTagXml.nodes('/tags/tag') AS T(TagValue)
)
INSERT INTO @MandatoryIdTable
-- Records where ALL tags match EXACTLY
SELECT E.Id [EventId], ED.Id [EventDateId]
FROM [dbo].[Events] E
INNER JOIN [dbo].[EventDates] ED ON ED.EventId = E.Id
WHERE ED.StartDate >= @StartDate
AND ED.EndDate <= @EndDate
AND ED.Archived = 0
AND NOT EXISTS (
SELECT T.Id, c.value
FROM MandatoryTags c
JOIN Tags T
ON c.[description] = T.[Description]
-- Add LIKE match on value
JOIN EventTags ET
ON C.[Value] LIKE '%' + ET.Value + '%'
EXCEPT
SELECT T.TagId, T.Value
FROM [EventTags] T
WHERE T.EventId = E.Id
)
这允许我进行类似的匹配,并且使用@SearchType参数,我可以运行原始查询,也可以相应地运行修改后的查询。+1用于SQL Fiddle演示。每个SQL问题都应该有这个!感谢您的反馈,这是一个好主意,但是它在标记描述上做了相似的匹配,而不是值。我尝试使用标记值查看类似的实现,但不幸的是,我看不出它是如何工作的。
-- Select ids with matching mandatory tags.
;WITH MandatoryTags AS
(
SELECT TagValue.value('(./value)[1]', 'nvarchar(100)') AS value,
TagValue.value('(./description)[1]', 'nvarchar(100)') AS [description]
FROM @MandatoryTagXml.nodes('/tags/tag') AS T(TagValue)
)
INSERT INTO @MandatoryIdTable
-- Records where ALL tags match EXACTLY or LIKE
SELECT E.Id [EventId], ED.Id [EventDateId]
FROM [dbo].[Events] E
INNER JOIN [dbo].[EventDates] ED ON ED.EventId = E.Id
WHERE ED.StartDate >= @StartDate
AND ED.EndDate <= @EndDate
AND ED.Archived = 0
AND EXISTS (
-- Just care about tag IDs here, not the values
SELECT T.Id
FROM MandatoryTags c JOIN Tags T
ON (
-- Toggle join type based on flag/switch
(@SearchType = 'EXACT' AND c.[description] = T.[Description])
OR
(@SearchType = 'LIKE' AND T.[Description] LIKE ('%' + c.[description] + '%'))
)
INTERSECT
SELECT T.TagId
FROM [EventTags] T
WHERE T.EventId = E.Id
)
JOIN EventTags ET
ON C.[Value] LIKE '%' + ET.Value + '%'
So, for example, the mandatory section becomes:
-- Select ids with matching mandatory tags.
;WITH MandatoryTags AS
(
SELECT TagValue.value('(./value)[1]', 'nvarchar(100)') AS value,
TagValue.value('(./description)[1]', 'nvarchar(100)') AS [description]
FROM @MandatoryTagXml.nodes('/tags/tag') AS T(TagValue)
)
INSERT INTO @MandatoryIdTable
-- Records where ALL tags match EXACTLY
SELECT E.Id [EventId], ED.Id [EventDateId]
FROM [dbo].[Events] E
INNER JOIN [dbo].[EventDates] ED ON ED.EventId = E.Id
WHERE ED.StartDate >= @StartDate
AND ED.EndDate <= @EndDate
AND ED.Archived = 0
AND NOT EXISTS (
SELECT T.Id, c.value
FROM MandatoryTags c
JOIN Tags T
ON c.[description] = T.[Description]
-- Add LIKE match on value
JOIN EventTags ET
ON C.[Value] LIKE '%' + ET.Value + '%'
EXCEPT
SELECT T.TagId, T.Value
FROM [EventTags] T
WHERE T.EventId = E.Id
)