【问题标题】:How to combine like and between in same statement (laravel Query Builder/model)如何在同一语句中组合 like 和 between (laravel Query Builder/model)
【发布时间】:2020-08-09 06:17:05
【问题描述】:

以下是计算机模型中的 HDD 列(我知道这不是存储数据的好格式,但它已经这样存储了)

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

我想从 HDD 列中获取存储在特定范围内的范围,例如,获取 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%'"

【问题讨论】:

    标签: mysql sql laravel laravel-7 laravel-7.x


    【解决方案1】:

    如果您只需要在 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;
    

    【讨论】:

      【解决方案2】:

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

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

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

      some python code 可以生成这样的表达式,但我找不到 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();
                      }
                  }
             });
          }
      
      

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-12
          • 2016-03-16
          • 2021-03-17
          • 1970-01-01
          相关资源
          最近更新 更多