ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 快速入门(五):查询语言 本章带你领略`ThinkPHP5.0`的查询语法,以及如何使用查询构建器进行查询操作,主要包括: - - [查询表达式](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u67E5u8BE2u8868u8FBEu5F0F) - [批量查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u6279u91CFu67E5u8BE2) - [快捷查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u5FEBu6377u67E5u8BE2) - [视图查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u89C6u56FEu67E5u8BE2) - [闭包查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u95EDu5305u67E5u8BE2) - [使用Query对象](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#-query-) - [获取数值](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u83B7u53D6u6570u503C) - [获取列数据](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u83B7u53D6u5217u6570u636E) - [聚合查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u805Au5408u67E5u8BE2) - [字符串查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u5B57u7B26u4E32u67E5u8BE2) - [时间(日期)查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#--3) - [分块查询](http://ihavenolimitations.xyz/thinkphp/thinkphp5_quickstart/147280#u5206u5757u67E5u8BE2) > 本章查询内容均配置了数据表前缀`think_`,因此统一使用`Db`类的`name`方法代替`table`方法进行举例说明。 ## 查询表达式 最普通的查询就是判断某个字段是否等于某个值,例如,我们查询`think_data`数据表中`id`等于1的数据,用法如下: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-number">1</span>) ->find(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 新手注意,如果没有使用`use`引入`Db`类的话 需要使用: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = \think\Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-number">1</span>) ->find(); dump(<span class="hljs-regexp">$result</span>); ``` ``` > #### 提示: > > - - - - - - > > `find`方法用于查找满足条件第一个记录(即使你的查询条件有多个符合的数据),如果查询成功,返回的是一个一维数组,没有满足条件的话则默认返回`null`(也支持设置是否抛出异常)。 生成的SQL语句是: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`id`</span> = <span class="hljs-number">1</span></span> ``` ``` 上述的查询其实等同于: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'='</span>, <span class="hljs-number">1</span>) ->find(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 使用表达式查询的时候,where方法的参数依次为: > #### where( 字段名,条件表达式,查询值 ) 可以支持的查询表达式包括如下: 表达式 含义 EQ、= 等于(=) NEQ、<> 不等于(<>) GT、> 大于(>) EGT、>= 大于等于(>=) LT、< 小于(<) ELT、<= 小于等于(<=) LIKE 模糊查询 \[NOT\] BETWEEN (不在)区间查询 \[NOT\] IN (不在)IN 查询 \[NOT\] NULL 查询字段是否(不)是NULL \[NOT\] EXISTS EXISTS查询 EXP 表达式查询,支持SQL语法> 其中条件表达式不区分大小写 下面就来查询`id`大于等于1的数据,使用如下代码: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'>='</span>, <span class="hljs-number">1</span>) ->limit(<span class="hljs-number">10</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 因为这里需要返回多条记录,因此这里我们使用了`select`方法,并且使用`limit`方法限制了返回的最多记录数。 > #### 提示: > > - - - - - - > > `select`方法用于查询数据集,如果查询成功,返回的是一个二维数组,如果没有满足条件的话则返回空数组(也支持设置是否需要抛出异常)。 生成的SQL语句是: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`id`</span> >= <span class="hljs-number">1</span> <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span></span> ``` ``` 如果使用EXP条件表达式的话,表示后面是原生的SQL语句表达式,例如上面的查询可以改成: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'exp'</span>, <span class="hljs-string">'>= 1'</span>) ->limit(<span class="hljs-number">10</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句和前面是一样的。 如果要查询id的范围,可以使用 ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) <span class="hljs-comment">// id 是 1、2、3 其中的数字</span> ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'in'</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句是: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">IN</span> (<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>) </span> ``` ``` 或者 ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) <span class="hljs-comment">// id 在 5到8之间的</span> ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'between'</span>, [<span class="hljs-number">5</span>, <span class="hljs-number">8</span>]) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句是: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">BETWEEN</span> <span class="hljs-number">5</span> <span class="hljs-keyword">AND</span> <span class="hljs-number">8</span> </span> ``` ``` 接下来,使用多个字段查询: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) <span class="hljs-comment">// id 在 1到3之间的</span> ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'between'</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>]) <span class="hljs-comment">// name 中包含think</span> ->where(<span class="hljs-string">'name'</span>, <span class="hljs-string">'like'</span>, <span class="hljs-string">'%think%'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 这样生成的查询语句为: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">BETWEEN</span> <span class="hljs-number">1</span> <span class="hljs-keyword">AND</span> <span class="hljs-number">3</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">`name`</span> <span class="hljs-keyword">LIKE</span> <span class="hljs-string">'%think%'</span></span> ``` ``` 如果要查询某个字段是否为`NULL`,可以使用: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'name'</span>, <span class="hljs-string">'null'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 这样生成的查询语句为: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`name`</span> <span class="hljs-keyword">IS</span> <span class="hljs-number">NULL</span></span> ``` ``` ## 批量查询 我们可以使用一个方法完成多个查询条件,例如上面的查询可以改成: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where([ <span class="hljs-string">'id'</span> => [<span class="hljs-string">'between'</span>, <span class="hljs-string">'1,3'</span>], <span class="hljs-string">'name'</span> => [<span class="hljs-string">'like'</span>, <span class="hljs-string">'%think%'</span>], ])->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 这样生成的查询语句还是和之前一样: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">BETWEEN</span> <span class="hljs-string">'1'</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">'3'</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">`name`</span> <span class="hljs-keyword">LIKE</span> <span class="hljs-string">'%think%'</span></span> ``` ``` 我们再来看一些复杂的用法,使用`OR`和`AND`混合条件查询,例如: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) <span class="hljs-comment">// name 中包含think</span> ->where(<span class="hljs-string">'name'</span>, <span class="hljs-string">'like'</span>, <span class="hljs-string">'%think%'</span>) ->where(<span class="hljs-string">'id'</span>, [<span class="hljs-string">'in'</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]], [<span class="hljs-string">'between'</span>, <span class="hljs-string">'5,8'</span>], <span class="hljs-string">'or'</span>) ->limit(<span class="hljs-number">10</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 或者使用批量方式: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where([ <span class="hljs-string">'id'</span> => [[<span class="hljs-string">'in'</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]], [<span class="hljs-string">'between'</span>, <span class="hljs-string">'5,8'</span>], <span class="hljs-string">'or'</span>], <span class="hljs-string">'name'</span> => [<span class="hljs-string">'like'</span>, <span class="hljs-string">'%think%'</span>], ])->limit(<span class="hljs-number">10</span>)->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句为: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> ( <span class="hljs-string">`id`</span> <span class="hljs-keyword">IN</span> (<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">BETWEEN</span> <span class="hljs-string">'5'</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">'8'</span> ) <span class="hljs-keyword">AND</span> <span class="hljs-string">`name`</span> <span class="hljs-keyword">LIKE</span> <span class="hljs-string">'%think%'</span> <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span></span> ``` ``` ## 快捷查询 如果你有多个字段需要使用相同的查询条件,可以使用快捷查询。例如,我们要查询id和status都大于0的数据,可以使用: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id&status'</span>, <span class="hljs-string">'>'</span>, <span class="hljs-number">0</span>) ->limit(<span class="hljs-number">10</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句为: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> ( <span class="hljs-string">`id`</span> > <span class="hljs-number">0</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">`status`</span> > <span class="hljs-number">0</span> ) <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span></span> ``` ``` 也可以使用or方式查询,例如: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id|status'</span>, <span class="hljs-string">'>'</span>, <span class="hljs-number">0</span>) ->limit(<span class="hljs-number">10</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句为: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> ( <span class="hljs-string">`id`</span> > <span class="hljs-number">0</span> <span class="hljs-keyword">OR</span> <span class="hljs-string">`status`</span> > <span class="hljs-number">0</span> ) <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span></span> ``` ``` ## 视图查询 如果需要快捷查询多个表的数据,可以使用视图查询,相当于在数据库创建了一个视图,但仅仅支持查询操作,例如: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::view(<span class="hljs-string">'user'</span>,<span class="hljs-string">'id,name,status'</span>) ->view(<span class="hljs-string">'profile'</span>,[<span class="hljs-string">'name'</span>=><span class="hljs-string">'truename'</span>,<span class="hljs-string">'phone'</span>,<span class="hljs-string">'email'</span>],<span class="hljs-string">'profile.user_id=user.id'</span>) ->where(<span class="hljs-string">'status'</span>,<span class="hljs-number">1</span>) ->order(<span class="hljs-string">'id desc'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句为: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT <span class="hljs-keyword">user</span>.<span class="hljs-keyword">id</span>,<span class="hljs-keyword">user</span>.<span class="hljs-keyword">name</span>,<span class="hljs-keyword">user</span>.<span class="hljs-keyword">status</span>,profile.<span class="hljs-keyword">name</span> <span class="hljs-keyword">AS</span> truename,profile.phone,profile.email <span class="hljs-keyword">FROM</span> think_user <span class="hljs-keyword">user</span> <span class="hljs-keyword">INNER</span> <span class="hljs-keyword">JOIN</span> think_profile profile <span class="hljs-keyword">ON</span> profile.user_id=<span class="hljs-keyword">user</span>.<span class="hljs-keyword">id</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">user</span>.<span class="hljs-keyword">status</span> = <span class="hljs-number">1</span> <span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> <span class="hljs-keyword">user</span>.<span class="hljs-keyword">id</span> <span class="hljs-keyword">desc</span></span> ``` ``` ## 闭包查询 `find`和`select`方法可以直接使用闭包查询: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>)->select(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-number">(<span class="hljs-regexp">$query</span>)</span> </span>{ <span class="hljs-regexp">$query</span>->where(<span class="hljs-string">'name'</span>, <span class="hljs-string">'like'</span>, <span class="hljs-string">'%think%'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'in'</span>, <span class="hljs-string">'1,2,3'</span>) ->limit(<span class="hljs-number">10</span>); }); dump(<span class="hljs-regexp">$result</span>); ``` ``` 生成的SQL语句是: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> <span class="hljs-string">`name`</span> <span class="hljs-keyword">LIKE</span> <span class="hljs-string">'%think%'</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">`id`</span> <span class="hljs-keyword">IN</span> (<span class="hljs-string">'1'</span>,<span class="hljs-string">'2'</span>,<span class="hljs-string">'3'</span>) <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">10</span></span> ``` ``` ## 使用Query对象 也可以事先封装Query对象,并传入select方法,例如: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$query</span> = <span class="hljs-keyword">new</span> \think\db\Query; <span class="hljs-regexp">$query</span>->name(<span class="hljs-string">'city'</span>)->where(<span class="hljs-string">'name'</span>, <span class="hljs-string">'like'</span>, <span class="hljs-string">'%think%'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-string">'in'</span>, <span class="hljs-string">'1,2,3'</span>) ->limit(<span class="hljs-number">10</span>); <span class="hljs-regexp">$result</span> = Db::select(<span class="hljs-regexp">$query</span>); dump(<span class="hljs-regexp">$result</span>); ``` ``` 使用`Query`对象的话,`select`方法之前调用的任何的链式操作都是无效。 ## 获取数值 如果仅仅是需要获取某行表的某个值,可以使用`value`方法: ``` <pre class="calibre18"> ``` <span class="hljs-comment">// 获取id为8的data数据的name字段值</span><span class="hljs-regexp">$name</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id'</span>, <span class="hljs-number">8</span>) ->value(<span class="hljs-string">'name'</span>); dump(<span class="hljs-regexp">$name</span>); ``` ``` name的结果为:`thinkphp` ## 获取列数据 也支持获取某个列的数据,使用`column`方法,例如: ``` <pre class="calibre18"> ``` <span class="hljs-comment">// 获取data表的name列</span><span class="hljs-regexp">$list</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'status'</span>, <span class="hljs-number">1</span>) ->column(<span class="hljs-string">'name'</span>); dump(<span class="hljs-regexp">$list</span>); ``` ``` 返回的结果类似下面: ``` <pre class="calibre18"> ``` <span class="hljs-keyword">array</span> (size=<span class="hljs-number">5</span>) <span class="hljs-number">0</span> => string <span class="hljs-string">'thinkphp'</span><span class="hljs-number">1</span> => string <span class="hljs-string">'onethink'</span><span class="hljs-number">2</span> => string <span class="hljs-string">'topthink'</span><span class="hljs-number">3</span> => string <span class="hljs-string">'kancloud'</span> ``` ``` 如果希望返回以id为索引的name列数据,可以改成: ``` <pre class="calibre18"> ``` <span class="hljs-comment">// 获取data表的name列 并且以id为索引</span><span class="hljs-regexp">$list</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'status'</span>, <span class="hljs-number">1</span>) ->column(<span class="hljs-string">'name'</span>, <span class="hljs-string">'id'</span>); dump(<span class="hljs-regexp">$list</span>); ``` ``` 返回的结果类似下面: ``` <pre class="calibre18"> ``` <span class="hljs-keyword">array</span> (size=<span class="hljs-number">5</span>) <span class="hljs-number">1</span> => string <span class="hljs-string">'thinkphp'</span><span class="hljs-number">2</span> => string <span class="hljs-string">'onethink'</span><span class="hljs-number">3</span> => string <span class="hljs-string">'topthink'</span><span class="hljs-number">4</span> => string <span class="hljs-string">'kancloud'</span> ``` ``` 如果需要返回以主键为索引的数据集,可以使用: ``` <pre class="calibre18"> ``` <span class="hljs-comment">// 获取data表的name列 并且以id为索引</span><span class="hljs-regexp">$list</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'status'</span>, <span class="hljs-number">1</span>) ->column(<span class="hljs-string">'*'</span>, <span class="hljs-string">'id'</span>); dump(<span class="hljs-regexp">$list</span>); ``` ``` 返回的结果类似下面: ``` <pre class="calibre18"> ``` <span class="hljs-keyword">array</span> (size=<span class="hljs-number">5</span>) <span class="hljs-number">1</span> => <span class="hljs-keyword">array</span> (size=<span class="hljs-number">3</span>) <span class="hljs-string">'id'</span> => int <span class="hljs-number">1</span><span class="hljs-string">'name'</span> => string <span class="hljs-string">'thinkphp'</span><span class="hljs-string">'status'</span>=> int <span class="hljs-number">1</span><span class="hljs-number">2</span> => <span class="hljs-keyword">array</span> (size=<span class="hljs-number">3</span>) <span class="hljs-string">'id'</span> => int <span class="hljs-number">1</span><span class="hljs-string">'name'</span> => string <span class="hljs-string">'onethink'</span><span class="hljs-string">'status'</span>=> int <span class="hljs-number">1</span><span class="hljs-number">3</span> => <span class="hljs-keyword">array</span> (size=<span class="hljs-number">3</span>) <span class="hljs-string">'id'</span> => int <span class="hljs-number">1</span><span class="hljs-string">'name'</span> => string <span class="hljs-string">'topthink'</span><span class="hljs-string">'status'</span>=> int <span class="hljs-number">1</span><span class="hljs-number">4</span> => <span class="hljs-keyword">array</span> (size=<span class="hljs-number">3</span>) <span class="hljs-string">'id'</span> => int <span class="hljs-number">1</span><span class="hljs-string">'name'</span> => string <span class="hljs-string">'kancloud'</span><span class="hljs-string">'status'</span>=> int <span class="hljs-number">1</span> ``` ``` ## 聚合查询 thinkphp为聚合查询提供了更便捷的方法,如下: ``` <pre class="calibre18"> ``` <span class="hljs-comment">// 统计data表的数据</span><span class="hljs-regexp">$count</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'status'</span>, <span class="hljs-number">1</span>) ->count(); dump(<span class="hljs-regexp">$count</span>); <span class="hljs-comment">// 统计user表的最高分</span><span class="hljs-regexp">$max</span> = Db::name(<span class="hljs-string">'user'</span>) ->where(<span class="hljs-string">'status'</span>, <span class="hljs-number">1</span>) ->max(<span class="hljs-string">'score'</span>); dump(<span class="hljs-regexp">$max</span>); ``` ``` 支持的聚合查询方法包括: 方法 说明 参数 count 统计数量 统计的字段名(可选) max 获取最大值 统计的字段名(必须) min 获取最小值 统计的字段名(必须) avg 获取平均值 统计的字段名(必须) sum 获取总分 统计的字段名(必须)## 字符串查询 在必要的时候,仍然可以使用原生的字符串查询,但建议是**配合参数绑定**一起使用,可以避免注入问题,例如: ``` <pre class="calibre18"> ``` <span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'id > :id AND name IS NOT NULL'</span>, [<span class="hljs-string">'id'</span> => <span class="hljs-number">10</span>]) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 可以直接在`where`方法中使用字符串查询条件,并支持第二个参数传入参数绑定,上面这个查询生成的SQL语句是: ``` <pre class="calibre18"> ``` <span class="hljs-operator">SELECT * <span class="hljs-keyword">FROM</span> <span class="hljs-string">`think_data`</span> <span class="hljs-keyword">WHERE</span> ( <span class="hljs-keyword">id</span> > <span class="hljs-string">'10'</span> <span class="hljs-keyword">AND</span> <span class="hljs-keyword">name</span> <span class="hljs-keyword">IS</span> <span class="hljs-keyword">NOT</span> <span class="hljs-number">NULL</span> )</span> ``` ``` ## 时间(日期)查询 > 首先需要在`think_data`数据表新增`create_time`字段,用于日期查询的字段类型推荐使用`datetime`类型。 `ThinkPHP5.0`的查询语言强化了对时间日期查询的支持,例如: ``` <pre class="calibre18"> ``` <span class="hljs-comment">// 查询创建时间大于2016-1-1的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'>'</span>, <span class="hljs-string">'2016-1-1'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); <span class="hljs-comment">// 查询本周添加的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'>'</span>, <span class="hljs-string">'this week'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); <span class="hljs-comment">// 查询最近两天添加的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'>'</span>, <span class="hljs-string">'-2 days'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); <span class="hljs-comment">// 查询创建时间在2016-1-1~2016-7-1的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'between'</span>, [<span class="hljs-string">'2016-1-1'</span>, <span class="hljs-string">'2016-7-1'</span>]) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` 日期查询对`create_time`字段类型没有要求,可以是`int/string/timestamp/datetime/date`中的任何一种,系统会自动识别进行处理。 还可以使用下面的人性化日期查询方式,例如: ``` <pre class="calibre18"> ``` <span class="hljs-comment">// 获取今天的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'today'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); <span class="hljs-comment">// 获取昨天的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'yesterday'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); <span class="hljs-comment">// 获取本周的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'week'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); <span class="hljs-comment">// 获取上周的数据</span><span class="hljs-regexp">$result</span> = Db::name(<span class="hljs-string">'data'</span>) ->whereTime(<span class="hljs-string">'create_time'</span>, <span class="hljs-string">'last week'</span>) ->select(); dump(<span class="hljs-regexp">$result</span>); ``` ``` ## 分块查询 分块查询是为查询大量数据的需要而设计的,假如`think_data`表已经有超过1万条记录,但是一次性取那么大的数据会导致内存开销非常之大,但确实又有这个需要(例如查询所有的数据并导出到`excel`),采用分块查询可以缓解这个问题。 使用分块查询,可以把1万条记录分成`100`次处理,每次处理`100`条记录,代码示例如下: ``` <pre class="calibre18"> ``` Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'status'</span>, <span class="hljs-string">'>'</span>, <span class="hljs-number">0</span>) ->chunk(<span class="hljs-number">100</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-number">(<span class="hljs-regexp">$list</span>)</span> </span>{ <span class="hljs-comment">// 处理100条记录</span><span class="hljs-keyword">foreach</span>(<span class="hljs-regexp">$list</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$data</span>){ } }); ``` ``` 第二个参数可以是有效的`callback`类型,包括使用闭包函数。 系统会按照主键顺序查询,每次查询`100`条,如果你不希望使用主键进行查询,或者没有主键的话,则需要指定查询的排序字段(但必须是唯一的),例如: ``` <pre class="calibre18"> ``` Db::name(<span class="hljs-string">'user'</span>) ->where(<span class="hljs-string">'status'</span>, <span class="hljs-string">'>'</span>, <span class="hljs-number">0</span>) ->chunk(<span class="hljs-number">100</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-number">(<span class="hljs-regexp">$list</span>)</span> </span>{ <span class="hljs-comment">// 处理100条记录</span><span class="hljs-keyword">foreach</span>(<span class="hljs-regexp">$list</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$data</span>){ } }, <span class="hljs-string">'uid'</span>); ``` ``` 然后交给`callback`进行数据处理,处理完毕后继续查询下一个`100`条记录,如果你需要在中途中断后续的查询,只需要在`callback`方法调用中返回`false`即可,例如: ``` <pre class="calibre42"> ``` Db::name(<span class="hljs-string">'data'</span>) ->where(<span class="hljs-string">'status'</span>,<span class="hljs-string">'>'</span>,<span class="hljs-number">0</span>) ->chunk(<span class="hljs-number">100</span>,<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-number">(<span class="hljs-regexp">$list</span>)</span></span>{ <span class="hljs-keyword">foreach</span>(<span class="hljs-regexp">$list</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$data</span>){ <span class="hljs-comment">// 返回false则中断后续查询</span><span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>; } }); ``` ```