【问题标题】:Join SQL Server tables on a like statement在 like 语句中加入 SQL Server 表
【发布时间】: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

我要做的是将URLTableStateTable 连接在一起,StateID 的值包含在 URL 表的 URL 中。我还没有真正弄清楚加入。我什至尝试只选择一张表并尝试按StateTable 中的值进行过滤。我试过做这样的事情:

SELECT  *
FROM URLTable
WHERE     EXISTS
    (SELECT  *
     FROM  StateTable
     WHERE URL LIKE '%' + StateID + '%')

即使这样也不起作用,因为它说我正在比较 uniqueidentifiervarchar

有什么方法可以使用 like 命令连接 2 个表,并且 like 命令不比较 2 个不兼容的变量?

谢谢!!

更新:让我添加一些我应该提到的其他内容。该查询用于构建分析报告。这些表是 CMS 分析包的一部分......因此更新或更改表结构不是一种选择。

其次,这些表会看到非常高的流量,因为它们正在捕获站点分析......所以性能是一个非常重要的问题。第三件事是,在我的示例中,我说的是 id= 但可能有多个值,例如id=guid&user=guid&date=date

更新 2:我刚刚意识到的另一件事让我感到恐惧的是,有时查询字符串从 GUID 中删除了破折号.. 有时没有.. 所以除非我弄错了,否则我不能将子字符串转换为Uniqueidentifier。有人可以确认吗?sigh。我确实使用了

REPLACE('-','',CONVERT(varchar(50), a.AutomationStateId))

但现在我非常担心这方面的性能问题,因为 URL 的表非常大。不过,这可能是野兽的本性,除非我能做些什么。

【问题讨论】:

    标签: sql tsql select join


    【解决方案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 表时,首先将数据子集提取到临时表,然后再加入它会有所帮助。其他时候临时表的开销比使用“丑陋”连接更大

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-18
        • 2011-04-28
        • 2020-12-23
        相关资源
        最近更新 更多