使用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中犯了一个错误,我想找到所有
的记录NOT' 不活跃' (不是真的)
也在哪里
'的 time_in ' < =' 2017-09-04 23:59:59'和' time_out ' > = ' 2017-09-04 00:00:00'
----或----
'的 TIME_OUT '是NULL并且' time_in ' < =' 2017-09-04 23:59:59'
所需的返回结果是:
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()方法。 这种方法很难预测基于SQL的SQL 当前查询状态。使用where()代替,因为它具有更多可预测性 并且更容易理解行为。1
所以我在两个方面寻求帮助:
感谢您的帮助。
答案 0 :(得分:1)
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' ]
])
答案 1 :(得分:0)
首先,IS NULL不等于!TRUE(!= 1)。这是第一个问题。固定的。
正确的SQL来自(感谢@cwallenpoole推进正确的方向)来自原始的简化查询:
->where( [ 'time_in <=' => $dateIn, 'inactive IS NULL',
'OR' =>(['time_out >=' => $dateOut,'time_out IS NULL' ])])
如果从架构中删除空值,则它看起来像:
->where( [ 'time_in <=' => $dateIn, 'inactive !=' =>1,
'OR' =>(['time_out >=' => $dateOut,'time_out IS NULL' ])])
这导致CakePHP查询:
WHERE
(
time_in <= '2017-09-04 23:59:59'
AND inactive IS NULL
AND (
time_out >= '2017-09-04 00:00:00'
OR time_out IS NULL
)
)
这会返回正确的行。