You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel查询构建器中如何结合LIKE与BETWEEN语句?

问题解答:无法直接用LIKE+BETWEEN实现你的需求,得换思路处理

首先直接给你结论:不能直接把LIKE和BETWEEN结合起来实现你要的筛选。原因很简单:BETWEEN对字符串是按字典顺序比较的,不是按实际存储容量的数值大小。比如你写的BETWEEN '%120GB%' and '%10TB%',字符串'10TB'的字典序比'120GB'小,所以这个条件实际上会筛选出所有字符串在'10TB'到'120GB'之间的内容,完全不是你要的容量范围。而且LIKE是匹配模式的操作,不能直接放在BETWEEN的两端当参数用。

那该怎么解决你的问题呢?因为你的HDD列是把多个存储单元拼接成的非结构化字符串,我们得先把这些单元拆分开,提取每个单元的容量数值和单位,转换成统一单位后再做范围判断。下面以MySQL为例(从你的SQL语法看应该用的是MySQL),给你两种实用的方案:

方案1:筛选记录并返回符合条件的存储单元

这个方案不仅会找出符合条件的服务器记录,还会把每个记录里符合120GB~1TB范围的存储单元单独列出来:

SELECT 
  sd.id,
  sd.HDD,
  GROUP_CONCAT(filtered_units.hdd_unit SEPARATOR ' ') AS matching_hdd_units
FROM server_details sd
-- 第一步:把HDD列拆成单个存储单元,去掉开头的"HDD"
JOIN (
  SELECT 
    id,
    TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(sd2.HDD, ' ', n.n), ' ', -1)) AS hdd_unit
  FROM server_details sd2
  -- 生成数字序列用于拆分(这里最多支持10个单元,不够可以加更多UNION ALL)
  JOIN (
    SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 
    UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10
  ) n ON n.n <= LENGTH(sd2.HDD) - LENGTH(REPLACE(sd2.HDD, ' ', '')) + 1
  WHERE TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(sd2.HDD, ' ', n.n), ' ', -1)) != 'HDD'
) filtered_units ON sd.id = filtered_units.id
-- 第二步:提取每个单元的容量数值和单位,转换为GB
JOIN (
  SELECT 
    hdd_unit,
    CAST(REGEXP_SUBSTR(hdd_unit, '[0-9.]+') AS DECIMAL(10,2)) AS capacity_num,
    REGEXP_SUBSTR(hdd_unit, '[A-Z]+') AS capacity_unit
  FROM filtered_units
) capacity_info ON filtered_units.hdd_unit = capacity_info.hdd_unit
-- 第三步:判断容量是否在120GB~1TB之间
WHERE 
  CASE
    WHEN capacity_info.capacity_unit LIKE '%TB%' THEN capacity_info.capacity_num * 1024
    WHEN capacity_info.capacity_unit LIKE '%GB%' THEN capacity_info.capacity_num
  END BETWEEN 120 AND 1024
GROUP BY sd.id, sd.HDD

方案2:仅筛选出包含符合条件存储单元的记录

如果只需要找出有至少一个符合条件存储单元的服务器记录,不需要单独列出单元,可以用EXISTS子查询:

SELECT * FROM server_details sd
WHERE EXISTS (
  SELECT 1
  FROM (
    -- 拆分HDD列成单个单元
    SELECT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(sd.HDD, ' ', n.n), ' ', -1)) AS hdd_unit
    FROM (
      SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 
      UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10
    ) n
    WHERE n.n <= LENGTH(sd.HDD) - LENGTH(REPLACE(sd.HDD, ' ', '')) + 1
      AND TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(sd.HDD, ' ', n.n), ' ', -1)) != 'HDD'
  ) units
  JOIN (
    -- 提取容量数值和单位
    SELECT 
      hdd_unit,
      CAST(REGEXP_SUBSTR(hdd_unit, '[0-9.]+') AS DECIMAL(10,2)) AS capacity_num,
      REGEXP_SUBSTR(hdd_unit, '[A-Z]+') AS capacity_unit
    FROM units
  ) capacity_info ON units.hdd_unit = capacity_info.hdd_unit
  -- 判断容量范围
  WHERE 
    CASE
      WHEN capacity_info.capacity_unit LIKE '%TB%' THEN capacity_info.capacity_num * 1024
      WHEN capacity_info.capacity_unit LIKE '%GB%' THEN capacity_info.capacity_num
    END BETWEEN 120 AND 1024
)

额外建议

其实你现在的HDD列存储方式是很不合理的,这种拼接字符串的形式会让查询、维护都很麻烦。如果可以的话,建议重构数据库结构:新建一个关联表(比如server_hdd),每个存储单元单独存一行,包含server_id(关联服务器表)、quantity(数量,比如4)、capacity(容量,比如1024)、unit(单位,比如GB)、interface(接口,比如SATA2)这些字段。这样后续的查询、统计都会简单高效很多。

内容的提问来源于stack exchange,提问作者Amitesh Bharti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 19:47:47