在 like 语句中加入 SQL Server 表
Posted
技术标签:
【中文标题】在 like 语句中加入 SQL Server 表【英文标题】:Join SQL Server tables on a like statement 【发布时间】:2012-04-18 15:49:09 【问题描述】:我希望这不是重复。我检查了搜索,但似乎找不到明确的答案。
我有一个表,它的主键设置为UniqueIdentifier
。我还有另一个表,它有一个 varchar
列,该列基本上包含一个带有查询字符串的 url,该查询字符串包含我的第一个表中的 guid。
所以我的 2 个表是这样的:
状态表
StateID StateName
EB06F84C-15B9-4397-98AD-4A63DA2A238E Active
URLTable
URL
page.aspx?id=EB06F84C-15B9-4397-98AD-4A63DA2A238E
我要做的是将URLTable
和StateTable
连接在一起,StateID
的值包含在 URL 表的 URL 中。我还没有真正弄清楚加入。我什至尝试只选择一张表并尝试按StateTable
中的值进行过滤。我试过做这样的事情:
SELECT *
FROM URLTable
WHERE EXISTS
(SELECT *
FROM StateTable
WHERE URL LIKE '%' + StateID + '%')
即使这样也不起作用,因为它说我正在比较 uniqueidentifier
和 varchar
。
有什么方法可以使用 like 命令连接 2 个表,并且 like 命令不比较 2 个不兼容的变量?
谢谢!!
更新:让我添加一些我应该提到的其他内容。该查询用于构建分析报告。这些表是 CMS 分析包的一部分......因此更新或更改表结构不是一种选择。
其次,这些表会看到非常高的流量,因为它们正在捕获站点分析......所以性能是一个非常重要的问题。第三件事是,在我的示例中,我说的是 id= 但可能有多个值,例如id=guid&user=guid&date=date
。
更新 2:我刚刚意识到的另一件事让我感到恐惧的是,有时查询字符串从 GUID 中删除了破折号.. 有时没有.. 所以除非我弄错了,否则我不能将子字符串转换为Uniqueidentifier
。有人可以确认吗?sigh。我确实使用了
REPLACE('-','',CONVERT(varchar(50), a.AutomationStateId))
但现在我非常担心这方面的性能问题,因为 URL 的表非常大。不过,这可能是野兽的本性,除非我能做些什么。
【问题讨论】:
【参考方案1】:将 StateID 转换为兼容类型,例如
WHERE URL LIKE '%' + CONVERT(varchar(50), StateID) + '%'
或
WHERE URL LIKE N'%' + CONVERT(nvarchar(50), StateID) + N'%'
如果 URL 是 nvarchar(...)
编辑
正如另一个答案中所指出的,这可能会导致大型表的性能不佳。 LIKE 与 CONVERT 结合将导致表扫描。这对于小型表可能不是问题,但如果性能成为问题,您应该考虑将 URL 拆分为两列。一列将包含“page.aspx?id=”,另一列包含 UNIQUEIDENTIFIER。然后可以更轻松地优化您的查询。
【讨论】:
【参考方案2】:您知道=
始终存在并且始终是UNIQUEIDENTIFIER
。然后你可以这样做:
WHERE CAST(SUBSTRING(URL, CHARINDEX('=',URL)+1,LEN(URL)) AS UNIQUEIDENTIFIER)=StateID
编辑
作为评论的一部分,您也可以使用JOIN
。像这样:
select
u.*
from
urltable
join statetable s
on CAST(SUBSTRING(URL, CHARINDEX('=',URL)+1,LEN(URL)) AS UNIQUEIDENTIFIER)=StateID
【讨论】:
如果我要使用知道我正在寻找的东西将始终遵循字符串“ID =”并且始终是以下 36 个字符,那会起作用吗?也许像 CAST(SUBSTRING(URL, CHARINDEX('ID=',URL)+1,36) AS UNIQUEIDENTIFIER)=StateID 之类的东西,性能如何? 我认为做很多字符串操作对性能来说并不是上帝。这一切都取决于您的表中有多少数据。您在所有答案中都有一些建议。运行它们并比较查询计划。但我仍然认为像 Phil 一样,在这种情况下创建一个包含唯一 ID 的新列是可取的 LEN(URL) 与 36 相比开销并不大。如果没有 36 则查询将失败。 感谢您的意见 Arion。这是客户对分析报告有特定要求的事情之一,而我一直坚持使用现有的表结构。更改或更新它会破坏他们更新 CMS 的能力。谢谢你的想法。这里的所有答案肯定都为我提供了我遇到的其他问题的答案。 :) 他们会反对额外的表和触发器。如果您可以有一个提取了 guid 的 ReportURL 表,并且此任务的索引会像热鼻涕一样运行。【参考方案3】:select u.* from urltable
join statetable s on url like N'%' + (convert(varchar(50),s.stateid) + N'%'
性能可能很糟糕
【讨论】:
感谢关于额外桌子的建议。实际上,我认为这是一个好主意,并且肯定会在不干扰现有结构的情况下工作。现在.. 老实说,我不是 DBA。关于构建和维护该表的最佳方法的任何建议?知道数据库看到如此多的流量,它通常托管在它自己的数据库服务器上,我可能会考虑将表添加到网站数据库而不是分析数据库。 如果新表在同一个数据库中或至少在同一个服务器中会更好,如果不是,则需要更多的工作。该表的大问题是架构是您能否为同一个 guid 获得多个 url 记录。 实际上,多一点调查告诉我,我肯定希望将表放在同一个数据库中。所以这是假设的。绝对要回答你的另一个问题。例如,状态表是一个包含特定类型访问者 ID 的表。 URL 表是一个复杂的表,它主要查看每个请求的 url 和 session id,除非它找到与 session 和 url 完全匹配的记录,否则它将创建一个新记录。我正在通过查看包含其 id 的 url 字段查询字符串来寻找为每个用户类型 id 访问的唯一基本 url 只要您可以简单地从正在插入/更新的 URL 记录中导出此新表的所有数据,您就是在笑着走向成功。使用触发器时要记住的主要事情是不要对它们发疯。【参考方案4】:如果您先构建一个临时表,并且可以选择为该临时表建立索引,您可能会获得性能提升。然后,您还可以修改(您的临时表的)架构,这可以为您提供加入选项。通常,在加入 BIG 表时,首先将数据子集提取到临时表,然后再加入它会有所帮助。其他时候临时表的开销比使用“丑陋”连接更大
【讨论】:
以上是关于在 like 语句中加入 SQL Server 表的主要内容,如果未能解决你的问题,请参考以下文章