在MySQL中选择一个VARCHAR值范围

时间:2018-10-22 07:23:23

标签: mysql sql

我的pip37 install virtualenv表上有一个名为VARCHAR(100)的{​​{1}}列,其值如下:

SerialNumber

如何在MySQL中选择DevicesSN10001 SN10002 SN10003 SN10004 ...etc 之间的所有记录?

MySQL版本为SN15000,我们不能假设序列号在SN20000之后总是5个数字。

3 个答案:

答案 0 :(得分:2)

  • 您可以使用Replace()函数将sudo pip install librosa 列中的SN子字符串替换为空字符串。
  • 然后,我们可以Cast()将修改后的字符串转换为无符号整数值。
  • 最终,根据需要使用SerialNumber条件来匹配范围。

您可以尝试以下操作:

Where

答案 1 :(得分:1)

由于您使用的是MySQL 8,因此可以利用正则表达式功能。您可以使用以下查询获取结果:

SELECT *
FROM Devices
WHERE SerialNumber REGEXP '^SN\\d+$'
AND REGEXP_REPLACE(SerialNumber, '[^\\d]+', '') BETWEEN 15000 and 20000;

首先,我们进行匹配以确保其为SN,后跟一些数字。其次,我们用数字替换所有不是数字的东西,然后检查它是否在15000到20000之间。可以看到一个示例here

虽然上述查询可以解决您的问题,但这会导致表上出现particularly nasty row-scans,这可能会导致表越长,性能就越差。

我建议重新格式化您的结构更好(特别是如果此表将变大,并且这样的搜索将经常发生),以便您可以使用索引进行搜索:

  1. 在设备上添加2列:string_partint_part。在两个字段(`string_part`, `int_part`)上添加索引。当您插入/更新数据时,要么创建触发器,要么以编程方式拆分数据,然后将拆分的数据插入各自的字段中。 (#3展示了如何使用虚拟列执行此操作。)然后,您可以有效地搜索数据库:

    SELECT * 
    FROM Devices 
    WHERE string_part = 'SN' AND int_part >= 15000 AND int_part <= 20000
    
  2. 确保所有数据的长度一致,即正好5个整数部分:(SN00001,SN10000)。然后只需按字符串比较即可。在这种情况下,SN1500永远不会出现在您的数据中(它将是SN01500),并且不会与以下内容匹配:

    SELECT * 
    FROM Devices 
    WHERE SerialNumber >= 'SN15000' AND SerialNumber <= 'SN20000'
    
  3. 使用虚拟列,并在该列上添加索引。可以找到一个示例here。注意查询时间(100ms至1ms):

    CREATE TABLE Devices (
      `SerialNumber` VARCHAR(20),
      `SerialNumberString` VARCHAR(20) GENERATED ALWAYS AS (REGEXP_SUBSTR(SerialNumber, '^[A-Za-z]+')) VIRTUAL,
      `SerialNumberInteger` INT(11) UNSIGNED GENERATED ALWAYS AS (REGEXP_SUBSTR(SerialNumber, '\\d+$')) VIRTUAL,
      INDEX `SerialNumberIndex` (`SerialNumberString`, `SerialNumberInteger`)
    ) DEFAULT charset=utf8 COLLATE=utf8_unicode_ci;
    

    您的查询:

    SELECT SerialNumber
    FROM Devices
    WHERE SerialNumberString = 'SN' AND SerialNumberInteger BETWEEN 15000 AND 20000;
    

答案 2 :(得分:1)

如果您想要'SN15000'和'SN20000'之间的所有序列号(包括两者),则可以只使用BETWEEN(否则,可以使用<>):< / p>

select *
from mytable
where serial_number  between 'SN15000' and 'SN20000';

如果允许使用较短和较长的序列号,请添加长度条件:

select *
from mytable
where serial_number  between 'SN15000' and 'SN20000'
and char_length(serial_number) = 7;