【问题标题】:Combining JOINs with OR将 JOIN 与 OR 结合
【发布时间】:2018-09-26 22:59:52
【问题描述】:

我不确定如何优化它。我需要从一个表中进行选择,将关键字搜索应用于各个表中的多个列:

SELECT  mt.Id
FROM    tbl_MyTable mt
JOIN    tbl_AnotherTable at
ON      mt.ForeignKey = at.Id
WHERE   <some stuff>
        AND (
            mt.Id IN (
                SELECT  mt2.Id
                FROM    tbl_MyTable mt2
                JOIN    @keywordLike kl
                ON      mt2.Name LIKE kl.Keyword
                WHERE   <same stuff as before, but for mt2>
            ) OR
            at.Id IN (
                SELECT  at2.Id
                FROM    tbl_AnotherTable at2
                JOIN    @keywordLike kl
                ON      at2.Name LIKE kl.Keyword
                        OR at2.Widget LIKE kl.Keyword
            ) -- in reality, the "keyword" search is applied to three other tables
        )

@keywordLike 是一个表变量,其中包含尝试匹配多个表中的多个列的字符串。

请注意,tbl_MyTable 中的 Id 将在任何时候返回 anything 匹配关键字搜索,而不是 all,这就是我不只是这样做的原因一堆JOINs。这些表非常大,我跳过的&lt;some stuff&gt; 部分被过滤掉了很多。看来我真正想要的是能够JOIN...ON...,但它们之间有一个OR,但这是我迄今为止想到的最佳选择。

以下是一些示例数据:

[[MyTable]]
Id      Name    ForeignKey
 1      Alice            1
 2      Bob              2

[[AnotherTable]]
Id      Name     Widget
 1      iPhone   Screen
 2      Android  Screen

如果@keywordLike 仅包含以下字符串:%A%,我们将返回:

  • 1(因为%A%匹配Alice
  • 2(因为 %A% 匹配 Android,而 Bob 的 ForeignKey 匹配该 ID

如果@keywordLike 包含%Alice%iPhone,我们将返回:

  • 1(因为%Alice%匹配Alice
  • 1(因为 %iPhone% 匹配 iPhone 和 Alice 的 ForeignKey 匹配该 ID

如果@keywordLike 包含Screen,我们将返回:

  • 1
  • 2

【问题讨论】:

  • (1) 用您正在使用的数据库标记您的问题。 (2) 解释逻辑——样本数据和期望的结果有帮助。
  • ????如果该示例数据没有帮助,请告诉我,我会扩展它。
  • 首先,JOIN @keywordLike 的语法无效 - 请发布不会引发错误的代码。我建议的下一件事是将您的所有IN ( 替换为WHERE EXISTS (
  • ...@keywordLike 是表变量吗?指出它会很有帮助。有时人们会尝试以这种方式执行动态 SQL,并且没有完整的代码(即变量定义),我不想假设任何事情。
  • 对不起,是的,@keywordLike 是一个表变量。在我的原始代码中,传入的关键字被预处理到其中。我会说清楚的。

标签: sql sql-server join sql-like


【解决方案1】:

此查询是否符合您的要求?

SELECT mt.Id
FROM tbl_MyTable mt JOIN
     tbl_AnotherTable at
     ON mt.ForeignKey = at.Id
WHERE mt.name LIKE @keywordlike OR
      at.name LIKE @keywordlike OR
      at.widget LIKE @keywordlike;

如果是这样,这将很难在 SQL Server 中提高效率。一种可能性是全文搜索,但即使是跨表也可能很棘手。

编辑:

如果@keywordlike 是一个表变量:

SELECT mt.Id
FROM tbl_MyTable mt JOIN
     tbl_AnotherTable at
     ON mt.ForeignKey = at.Id
WHERE EXISTS (SELECT 1 FROM @keywordlike kl WHERE mt.name LIKE kl.keyword) OR
      EXISTS (SELECT 1 FROM @keywordlike kl WHERE at.name LIKE kl.keyword) OR
      EXISTS (SELECT 1 FROM @keywordlike kl WHERE at.widget LIKE kl.keyword); 

【讨论】:

  • 对不起,我没有指出@keywordLike 是一个表变量。
  • 嗯.. 有什么理由做SELECT 1 n 次吗?不是和WHERE EXISTS (SELECT 1 FROM @keywordLike kl WHERE (mt.name LIKE kl.keyword OR at.name LIKE kl.keyword OR ...)一样吗?
  • @moswald 。 . .不,没有理由。我只是遵循与第一个答案相同的结构。如果您进行相等比较,or 可能会使优化器更难处理用户索引,但这不是问题。
猜你喜欢
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 2013-01-24
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多