使用CakePHP 3.4.12版和MySQL ...
我在使用SQL时遇到了麻烦,然后最重要的是将SQL导入CakePHP。我想查看今天可能已进入和退出,今天或之前已进入,今天或之后已退出,或者它们今天或之前进入而仍然没有退出时间的记录。并跳过所有标记为非活动(inactive = true)的记录。

数据摘录:

id  name    time_in             time_out            inactive
174 smith   8/15/2017 21:00     8/15/2017 21:22     NULL
175 roberts 8/15/2017 21:21     8/15/2017 21:21     NULL
176 Wagner  9/2/2017 4:40       9/3/2017 18:29      0
177 JAmes   9/1/2017 3:35       NULL                0
178 john    9/4/2017 3:59       9/4/2017 22:22      NULL
180 erwer   9/4/2017 4:01       NULL                1
181 waynbe  9/4/2017 4:02       NULL                NULL
182 Roger   9/4/2017 22:21      9/4/2017 22:22      NULL
183 Felix   9/4/2017 22:24      NULL                NULL


如果我在SQL中犯了一个错误,我想查找所有


  不是“无效”(不是TRUE)


还有哪里


  'time_in' =
  '2017-09-04 00:00:00'
  
   - - 要么 - -
  
  'time_out'为NULL AND'time_in'

所需的返回结果是:

id  name    time_in             time_out            inactive
177 JAmes   9/1/2017 3:35       NULL                0
178 john    9/4/2017 3:59       9/4/2017 22:22      NULL
181 waynbe  9/4/2017 4:02       NULL                NULL
182 Roger   9/4/2017 22:21      9/4/2017 22:22      NULL
183 Felix   9/4/2017 22:24      NULL                NULL


我试图实现的条件SQL是:

WHERE (time_in <= '2017-09-04 23:59:59' AND time_out >= '2017-09-04 00:00:00')
OR (isnull(time_out) AND time_in <= '2017-09-04 23:59:59')
AND inactive != 1


这给出了结果,并且缺少数据:

id  name    time_in             time_out            inactive
177 JAmes   9/1/2017 3:35       NULL                0
178 john    9/4/2017 3:59       9/4/2017 22:22      NULL
182 Roger   9/4/2017 22:21      9/4/2017 22:22      NULL


但是,在使用以下方法尝试CakePHP时:

$query= $this->StationEntries->find('all')
            ->andWhere(['time_in <='=> $dateIn, 'time_out >='=>$dateOut])
            ->orWhere(['isnull(time_out)', 'time_in <='=> $dateIn])
            ->andWhere(['inactive !='=>true]);


创建SQL:

WHERE
(
 (
  (
    time_in <= '2017-09-04 23:59:59'
    AND time_out >= '2017-09-04 00:00:00'
  )
  OR (
    isnull(time_out)
    AND time_in <= '2017-09-04 23:59:59'
  )
 )
 AND inactive != 1
)


这将返回以下结果,并且丢失更多记录。

id  name    time_in             time_out            inactive
177 JAmes   9/1/2017 3:35       NULL                0


以下内容可以正常工作,但它不会过滤掉不活动的记录。

$query= $this->StationEntries->find('all')
        ->where(['time_in <='=> $dateIn, 'time_out >='=>$dateOut])
        ->orWhere(['isnull(time_out)', 'time_in <='=> $dateIn]);


我在书中读过:


  从3.5.0版开始,不推荐使用orWhere()方法。
  这种方法难以根据
  当前查询状态。使用where()代替,因为它更容易发生
  并且更容易理解行为。1


因此,我在两个方面寻求帮助:


我在SQL WHERE子句中的错误在哪里,应该是什么?
如何在不使用orWhere()方法的情况下将其转换为CakePHP查询生成器,以及如何做到这一点?


谢谢您的帮助。

最佳答案

Per docs, to add an 'OR' clause, you need to have the 'OR' be the key in the array。我认为您正在寻找:

->where(
   [
      'time_in <=' => $dateIn, 'time_out >=' => $dateOut,
      'OR' => [
         ['time_out IS NULL', 'time_in <=' => $dateIn
      ]
   ]
)->andWhere( [ 'inactive !=' => 1 ] )


基本上,这应该导致:

(
   (time_in < dateIn AND time_out < dateOut)
   OR ( time_out IS NULL AND time_in < dateIn)
)
AND ( inactive != 1 )


您可以简化为:

->where( [ 'time_in <=' => $dateIn ], [ 'inactive !=' => 1 ] )
->andWhere(
[
   'time_out >=' => $dateOut,
   'OR' => [ 'time_out IS NULL' ]
])

10-05 20:34
查看更多