【问题标题】:Provide the values for a 'like' function from a specific column in a Table?提供表中特定列的“like”函数的值?
【发布时间】:2019-10-04 05:21:52
【问题描述】:

我正在使用 SQL Server 2014 并且我需要一个 T-SQL 查询,该查询使用 like 函数在表 (t1) 的特定列 (c1) 上运行,以查明它是否包含来自在另一个表 (t2) 的列 (c2) 中找到的代码列表。

为简化起见,以下是场景和预期输出:

表 t1:

ID       Notes
101      (free text in this column)
102      ...
...      ...
115000   ...

表t2(300多个代码列表):

Code
FR110419
GB150619
...
DE111219

我在寻找什么:

SELECT ID 
FROM t1
WHERE t1.Notes like (SELECT Code FROM t2)

由于 like 运算符需要 '%' 才能工作,我对如何构造该行感到困惑。

我对@9​​87654328@ 进行了一些研究,我遇到的最接近的解决方案是mysql 问题:how to use LIKE with column name

我们将不胜感激任何类型的帮助。

【问题讨论】:

  • Code列有空值怎么办?全部归还还是什么都不归?
  • 代码列不会有 NULL 值,因为它是使用的现有代码的列表。

标签: sql sql-server string tsql sql-like


【解决方案1】:

您似乎在寻找JOIN

SELECT ID 
FROM t1
INNER JOIN t2 ON t1.Notes LIKE '%' + t2.Code + '%'

如果不同的Codes 可能出现在同一个Note 中,也可以选择使用带有相关子查询的EXISTS 条件,因为这样可以避免在输出中重复记录:

SELECT ID
FROM t1
WHERE EXISTS (
    SELECT 1 FROM t2 WHERE t1.Notes LIKE '%' + t2.Code + '%'
)

【讨论】:

    【解决方案2】:

    您可以像这样使用cross applycharindex

    --Loading data
    create table t1 (id varchar(10));
    insert into t1 (id) values ('100100'),('200100'),('300100')
    insert into t1 (id) values ('100200'),('200200'),('300200')
    insert into t1 (id) values ('100300'),('200300'),('300300')
    insert into t1 (id) values ('0100'),('0200'),('0300')
    insert into t1 (id) values ('00010'),('00020'),('00030')
    
    create table t2 (id varchar(10));
    insert into t2 (id) values ('020'),('010')
    
    select t.id
    from t1 as t
    cross apply t2 as t2
    --where charindex(t2.id,t.id) > 0 -- simulates a double % one at the beginning and one at the end
    --where charindex(t2.id,t.id) = 1 -- simulates a % at the beginning
    where charindex(t2.id,t.id) = len(t.id)-len(t2.id)+1 -- simulates a % at the end
    

    唯一的问题是桌子很大,这可能是一个缓慢的解决方案。

    【讨论】:

    • 这真是太好了。 CHARINDEX 将比 LIKE 语句执行得更好。
    【解决方案3】:

    在已经发布的内容的基础上,您可以创建一个索引视图来真正加快速度。

    使用 CTE6 的样本数据...

    --Loading data
    create table t1 (id varchar(10));
    insert into t1 (id) values ('100100'),('200100'),('300100')
    insert into t1 (id) values ('100200'),('200200'),('300200')
    insert into t1 (id) values ('100300'),('200300'),('300300')
    insert into t1 (id) values ('0100'),('0200'),('0300')
    insert into t1 (id) values ('00010'),('00020'),('00030')
    
    create table t2 (id varchar(10));
    insert into t2 (id) values ('020'),('010')
    GO
    
    --  The View
    CREATE VIEW dbo.vw_t1t2 WITH SCHEMABINDING AS
    SELECT     t1 = t1.id, t2 = t2.id, cb = COUNT_BIG(*)
    FROM       dbo.t1 AS t1
    CROSS JOIN dbo.t2 AS t2
    WHERE      CHARINDEX(t2.id,t1.id) > 0
    GROUP BY   t1.id, t2.id
    GO
    -- The index (may need to add something else to make UNIQUE)
    CREATE UNIQUE CLUSTERED INDEX uq_cl_vwt1t2 ON dbo.vw_t1t2(t1,t2);
    GO
    

    这对于 SELECT 语句执行得非常好,但可能会影响对 t1 和 t2 的数据修改,因此请确保使用尽可能小的数据类型,并且只包含您确定需要的列(Varchar(10) 很好)。我包括 COUNT_BIG() 因为它在利用 GROUP BY 的索引视图中是必需的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 2020-10-21
      • 2018-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多