繁体   English   中英

如何在同一个语句中组合 like 和 between (laravel Query Builder/model)

[英]How to combine like and between in same statement (laravel Query Builder/model)

以下是来自计算机 model 的 HDD 专栏(我知道这不是存储数据的好格式,但它已经这样存储了)

     HDD
4x2TBSATA2
2x2TBSATA2
8x2TBSATA2
4x1TBSATA2
2x120GBSSD
4x480GBSSD

我想从存储在特定范围内的 HDD 列中获取范围,例如,如果 output 应获取 120GB 到 1TB 之间的存储

4x1TBSATA2
2x120GBSSD
4x480GBSSD

我想知道是否可以在同一个语句中组合 like 和 between ?

我尝试了以下不起作用。

select * from `server_details` where `HDD` between '%120GB%' and '%10TB%'

select * from `server_details` where `HDD` between "Like '%120GB%'" and "LIKE '%10TB%'"

如果您只需要在 SQL 中进行操作,请提取大小部分,将其转换为数字,然后进行比较。

select *,
  cast(`HDD` as unsigned)*
  cast(substr(`HDD`,LOCATE('x',`HDD`)+1) as unsigned)*
  (case when`HDD` LIKE '%TB%' then 1000 else 1 end) as GB
from `server_details`
where
  cast(`HDD` as unsigned)*
  cast(substr(`HDD`,LOCATE('x',`HDD`)+1) as unsigned)*
  (case when`HDD` LIKE '%TB%' then 1000 else 1 end)
  between 120 and 10000;

在数据库中,在HDD列中,不应存储 120GB、10TB 之类的字母数字值,而应存储 120、10000 之类的数字值。请尝试以下查询。

$hdds = DB::table('server_details')
           ->whereBetween('HDD', [120, 10000])
           ->get();

您不能在通配符查询中使用 between。 也许可以编写一个正则表达式来匹配您需要的内容,例如:

select * from `server_details` where `HDD` regexp '1[2-9]\dGB|[2-9]\d\dGB|\dTB|10TB'

但正如您所看到的,这是一个非常具体的表达式,基于您所写的内容,每个不同的限制都需要不同的表达式。

一些 python 代码可以生成这样的表达式,但我找不到 PHP 代码(通过一些非常基本的谷歌搜索)

另一种解决方案(也是我个人推荐的)是将容量添加为单独的列:

迁移当前表:

class AddCapacityColumnMigration extends Migration {

    public function up()
    {
        Schema::table('computers', function (Blueprint $table) {
             $table->bigInt('capacityMB')->nullable();
        });
        Computer::chunk(100, function ($computers) {
            foreach ($computers as $computer) {
                if (preg_match('/(\d+)x(\d+)(M|G|T)B/',$computer->HDD,$m) {
                    $capacity = $m[1];
                    $capacity *= $m[3] === 'M' ? 1 : ($m[3] === 'G' ? 1000 : 1000000 );
                    $computer->capacityMB = $capacity * $m[2];
                    $computer->save();
                }
            }
       });
    }

然后,您可能希望在 model 中添加creatingupdating事件,以确保始终设置新的 capacityMB 列。 完成所有这些后,您的查询就很简单了:

select * from `server_details` where `capacityMB` between 120000 and 10000000

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM