使用通配符在 varchar 中选择 WHERE 问题示例记录

问题描述

假设我有一张这样的桌子

CREATE TABLE Parts (ID int,part_number varchar(100),isActive tinyint);

和这些样本记录

|ID | part_number   | isActive|
===============================
  1 | 1N3.805.327   |  1      
  2 | 1N3.805.327.B |  1
  3 | 1N3.804.108.B |  1
  4 | 1N3.804.108.C |  1
  5 | 1N3.804.107.B |  1
  6 | 1N3.804.107.C |  1
  7 | 1N3.804.106.A |  1
  8 | 1N3.804.105.A |  1

问题

我想将 where in 子句与通配% 运算符结合使用 在我的 dbfiddle sample 中,我尝试了 the string function find_in_setcomparison operator in()。两者都不起作用:

-- without wildcard the query works
SELECT * FROM Parts WHERE part_number in ('1N3.804.108.B','1N3.804.106.A'); -- 2

-- with wildcard no records are returned
SELECT * FROM Parts WHERE part_number in ('1N3.804.108%','1N3.804.106%'); -- 0 
SELECT * FROM Parts WHERE FIND_IN_SET(part_number,'1N3.804.108%,1N3.804.106%'); -- 0

问题

  1. 我想我可以使用 WHERE LEFT(part_number,11) in ('1N3.804.108','1N3.804.106') 但我不知道这是否有任何缺点。
  2. 有没有办法在 in() 中使用通配符?

示例记录

INSERT INTO 
    Parts(ID,part_number,isActive)
VALUES
    (1,'1N3.805.327',1),(2,'1N3.805.327.B',(3,'1N3.804.108.B',(4,'1N3.804.108.C',(5,'1N3.804.107.B',(6,'1N3.804.107.C',(7,'1N3.804.106.A',(8,'1N3.804.105.A',1);

解决方法

当您想使用 OR 时,请使用 REGEXP

CREATE TABLE Parts (ID int,part_number varchar(100),isActive TINYINT);
INSERT INTO 
    Parts(ID,part_number,isActive)
VALUES
    (1,'1N3.805.327',1),(2,'1N3.805.327.B',(3,'1N3.804.108.B',(4,'1N3.804.108.C',(5,'1N3.804.107.B',(6,'1N3.804.107.C',(7,'1N3.804.106.A',(8,'1N3.804.105.A',1);
✓

✓
SELECT * FROm Parts WHeRE part_number REGEXP '^(1N3.804.108|1N3.804.106)'
ID | part_number   | isActive
-: | :------------ | -------:
 3 | 1N3.804.108.B |        1
 4 | 1N3.804.108.C |        1
 7 | 1N3.804.106.A |        1

MySQL 只能 UNION 一定数量的表。我想大约是 53。

在零件编号上有索引,这将是最快的。

SELECT * FROm Parts WHeRE part_number REGEXP '^1N3.804.108'
UNION all
SELECT * FROm Parts WHeRE part_number REGEXP '^1N3.804.106'
ID | part_number   | isActive
-: | :------------ | -------:
 3 | 1N3.804.108.B |        1
 4 | 1N3.804.108.C |        1
 7 | 1N3.804.106.A |        1
SELECT * FROm Parts WHeRE part_number LIKE '1N3.804.108%'
UNION all
SELECT * FROm Parts WHeRE part_number LIKE '1N3.804.106%'
ID | part_number   | isActive
-: | :------------ | -------:
 3 | 1N3.804.108.B |        1
 4 | 1N3.804.108.C |        1
 7 | 1N3.804.106.A |        1

dbfiddle here

,

你也可以试试

select *,REGEXP_LIKE(part_number,[pattern]) as pattern_test from Parts 
where pattern_test is TRUE

首先,您将创建您感兴趣的模式并将其应用到您希望应用到的列上。如果 pattern_test 与您的模式匹配,它将返回 true,然后您可以过滤该 [where 子句]