我的pip37 install virtualenv
表上有一个名为VARCHAR(100)
的{{1}}列,其值如下:
SerialNumber
如何在MySQL中选择Devices
和SN10001
SN10002
SN10003
SN10004
...etc
之间的所有记录?
MySQL版本为SN15000
,我们不能假设序列号在SN20000
之后总是5个数字。
答案 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,这可能会导致表越长,性能就越差。
我建议重新格式化您的结构更好(特别是如果此表将变大,并且这样的搜索将经常发生),以便您可以使用索引进行搜索:
在设备上添加2列:string_part
和int_part
。在两个字段(`string_part`, `int_part`)
上添加索引。当您插入/更新数据时,要么创建触发器,要么以编程方式拆分数据,然后将拆分的数据插入各自的字段中。 (#3展示了如何使用虚拟列执行此操作。)然后,您可以有效地搜索数据库:
SELECT *
FROM Devices
WHERE string_part = 'SN' AND int_part >= 15000 AND int_part <= 20000
确保所有数据的长度一致,即正好5个整数部分:(SN00001,SN10000)。然后只需按字符串比较即可。在这种情况下,SN1500
永远不会出现在您的数据中(它将是SN01500
),并且不会与以下内容匹配:
SELECT *
FROM Devices
WHERE SerialNumber >= 'SN15000' AND SerialNumber <= 'SN20000'
使用虚拟列,并在该列上添加索引。可以找到一个示例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;