我在这个名为MM的列中有这个数字4.40-4.85X3.60。如何在mysql查询中复杂的数字之间进行搜索?
我想搜索器,可通过MySQL的更大或低于3点从每个编号为exampel号码:
[4.37-4.43] - ,之后[4.82-4.88] X [0-9]的数X可以是任何数字。
我试过使用正则表达式,但我没有找到真正有用的东西,请告知。
我在这个名为MM的列中有这个数字4.40-4.85X3.60。如何在mysql查询中复杂的数字之间进行搜索?
我想搜索器,可通过MySQL的更大或低于3点从每个编号为exampel号码:
[4.37-4.43] - ,之后[4.82-4.88] X [0-9]的数X可以是任何数字。
我试过使用正则表达式,但我没有找到真正有用的东西,请告知。
一种方法是将字符串“拆分”,以便从中获取所需的单独组件。假设该字符串总是使用“ - ”和“X”的三个组成部分,在此查询表达式分离将“拆分”它给你:
SELECT SUBSTRING_INDEX(@n,'-',1) AS s1
, SUBSTRING_INDEX(SUBSTRING_INDEX(@n,'-',-1),'X',1) AS s2
, SUBSTRING_INDEX(@n,'X',-1) AS s3
FROM (SELECT @n := '4.40-4.85X3.6') n
然后可以在每次这些表达式转换为数值。
请注意,MySQL可能会(默默地)丢失精度数字,可能返回“0”表示无法转换为数字的字符串,或者MySQL可能会抛出异常或警告。
因此,请谨慎选择DECIMAL(m,n)的比例和精度,以避免溢出并正确处理舍入/截断。您示例中显示的所有数据都适合DECIMAL(3,2),但这仅仅是一个示例,并不是所有数据的保证。
我会在内联视图中执行“搜索参数”字符串的转换,然后将它加入到要搜索的表中。
事情是这样的:
SELECT t.MM
FROM mytable t
JOIN (SELECT CONVERT(SUBSTRING_INDEX(@n,'-',1) ,DECIMAL(6,2)) AS s1
, CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(@n,'-',-1),'X',1),DECIMAL(6,2)) AS s2
, CONVERT(SUBSTRING_INDEX(@n,'X',-1) ,DECIMAL(6,2)) AS s3
FROM (SELECT @n := '4.40-4.85X3.6') n
) p
ON ABS(p.s1 - CONVERT(SUBSTRING_INDEX(t.MM,'-',1),DECIMAL(6,2)))
<= .03
AND ABS(p.s2 - CONVERT(SUBSTRING_INDEX(SUBSTRING_INDEX(t,MM,'-',-1),'X',1),DECIMAL(6,2))
<= .03
连接谓词是距离搜索参数减去(衍生)数值从表中从(衍生)数值值,检查差异的问题。
同样,正如我之前提到的,在转换为DECIMAL操作的情况下,请注意字符串不是预期格式的问题,太大而不适合缩放(溢出)的值以及舍入/截断。你可能会得到意想不到的结果(MySQL可能会失去精度并且无声无息地伸缩,或者可能会抛出异常和/或警告。(行为取决于会话的sql_mode设置。)
对这三个数字使用单独的列,这将解决您的所有问题。
否则,使用类似:
WHERE
CAST(SUBSTR(MM FROM 1 FOR (@tmp1:=POSITION("-" IN MM))) AS DECIMAL(3,2))
BETWEEN 4.37 AND 4.43
AND
CAST(SUBSTR(MM FROM @tmp1 FOR POSITION("X" IN MM)[email protected]) AS DECIMAL(3,2))
BETWEEN 4.82 AND 4.88
,但请记住,这对你可能对你的表的任何索引完全螺丝。
将它分解为搜索'-'和'X'在字符串中的位置以及那三个部分然后检查(用'between')的部分会更好 - – 2012-07-18 16:05:27
@Ωmega也许,我只是假设数字是定点的,但是如果它们是10或更高,那么它又会如何。好的,将会被编辑。 – 2012-07-18 16:07:37
哪些正则表达式不起作用?示例 – 2012-07-18 15:58:44
'4.40-4.85X3.60'不是数字 – Shikiryu 2012-07-18 15:59:52
正则表达式不是正确的选择,你最好使用sql字符串函数将列值分成三部分,然后检查这些值是否在范围内。 – 2012-07-18 16:01:13