简体   繁体   English

CakePHP多条件SQL语句

[英]CakePHP Multi-Conditional SQL statement

Using CakePHP version 3.4.12 and MySQL... I am having trouble with the SQL and then on top of that getting the SQL into CakePHP. 使用CakePHP版本3.4.12和MySQL ...我在使用SQL时遇到了麻烦,然后在将SQL导入CakePHP时遇到了麻烦。 I want to see records that may have entered and exited today, entered today or before and may have exited today or later, or they entered today or before and still have no exit time. 我想查看今天可能已进入和退出,今天或之前已进入,今天或之后已退出,或者它们今天或之前进入但仍没有退出时间的记录。 And skip over any records marked as inactive (inactive=true). 并跳过所有标记为非活动(inactive = true)的记录。

Excerpt of Data: 数据摘录:

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

In Case I have made a mistake in the SQL, I want to find all records that are 如果我在SQL中犯了一个错误,我想查找所有

NOT ' inactive ' (not TRUE) 不是“ 非活动状态 ”(不是TRUE)

also where 还有哪里

' time_in ' <= '2017-09-04 23:59:59' AND ' time_out ' >= '2017-09-04 00:00:00' 'time_in'<= '2017年9月4日23时59分59秒'与'TIME_OUT'> = '2017年9月4日00:00:00'

---- OR ---- - - 要么 - -

' time_out ' is NULL AND ' time_in ' <= '2017-09-04 23:59:59' ' time_out '为NULL AND'time_in '<='2017-09-04 23:59:59'

Desired returned results are: 所需的返回结果是:

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

The conditional SQL I am attempting to achieve is: 我试图实现的条件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 

This gives the results and is missing data: 这给出了结果,并且缺少数据:

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

However, when attempting in CakePHP using: 但是,在使用以下方法尝试CakePHP时:

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

Creates the SQL: 创建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
) 

This is returning the following results and is missing even more records. 这将返回以下结果,并且丢失更多记录。

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

The following does work correctly except it doesn't filter out the inactive records. 以下内容可以正常工作,只是它不会过滤掉不活动的记录。

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

I have read in the book: 我在书中读过:

As of 3.5.0 the orWhere() method is deprecated. 从3.5.0版开始,不推荐使用orWhere()方法。 This method creates hard to predict SQL based on the current query state. 这种方法很难根据当前查询状态预测SQL。 Use where() instead as it has more predicatable and easier to understand behavior. 请改用where(),因为它更容易被发现并且更容易理解行为。 1 1

So I am asking for help in two areas: 因此,我在两个方面寻求帮助:

  1. Where is my mistake in the SQL WHERE clause and what should it be? 我在SQL WHERE子句中的错误在哪里,应该是什么?
  2. How to translate that into CakePHP Query builder and how to do it while avoiding the orWhere() method? 如何在避免orWhere()方法的情况下将其转换为CakePHP查询生成器,以及如何做到这一点?

Thank you for your help. 谢谢您的帮助。

Per docs, to add an 'OR' clause, you need to have the 'OR' be the key in the array . 根据文档,要添加“ OR”子句,您需要将“ OR”作为array中的键 I think you're looking for: 认为您正在寻找:

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

Basically, that should result in: 基本上,这应该导致:

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

You could simplify to: 您可以简化为:

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

First off, IS NULL is not equivalent to !TRUE ( != 1 ). 首先,IS NULL不等于!TRUE(!= 1)。 That was the first problem. 那是第一个问题。 Fixed. 固定。

Correct SQL came from (Thanks to @cwallenpoole for a push in the right direction) a simplifed query from the original: 正确的SQL来自原始的简化查询(感谢@cwallenpoole朝着正确的方向推进):

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

If you remove nulls from your schema then it would look like: 如果从架构中删除空值,则它将类似于:

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

This results in CakePHP query of: 结果导致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
    )
  ) 

And this returns the correct Rows. 这将返回正确的行。

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

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