26
2019.2
查询语言
作者: POPASP
POPASP内置了非常灵活的查询方法,可以快速的进行数据查询操作,查询条件可以用于CURD等任何操作,作为where方法的参数传入即可,下面来一一讲解查询语言的内涵。
### 查询方式
POPASP可以支持直接使用字符串作为查询条件,但是大多数情况推荐使用索引数组或者对象来作为查询条件,因为会更加安全。
### 一、使用字符串作为查询条件
这是最传统的方式,但是安全性不高,例如:
```brush:vb
set rs = B_("post").where("not is_delete and is_display").select()
```
最后生成的SQL语句是
```brush:sql
SELECT * FROM `post` WHERE not is_delete and is_display
```
### 二、使用Dictionary对象作为查询条件
```brush:vb
set dict = D_ '快速创建一个Dictionary对象
dict("is_delete") = 1
dict("is_display") = 1
set rs = B_("post").where(dict).select()
```
最后生成的SQL语句是
```brush:sql
SELECT * FROM `post` WHERE is_delete = True AND is_display = True
```
须注意的是,Dictionary每个元素之间生成的逻辑关系为AND
### 表达式查询
上面的查询条件仅仅是一个简单的相等判断,可以使用查询表达式支持更多的SQL查询语法,并且可以用于数组或者对象方式的查询(下面仅以数组方式为例说明),查询表达式的使用格式:
> map("字段名") = array("表达式","查询条件")
表达式不分大小写,支持的查询表达式有下面几种,分别表示的含义是:
| 表达式 | 含义 |
| -------- | ----- |
| EQ | 等于(=) |
| NEQ | 不等于(<>) |
| GT | 大于(>) |
| EGT | 大于等于(>=) |
| LT | 小于(<) |
| ELT | 小于等于(<=) |
| LIKE | 模糊查询 |
| [NOT] BETWEEN | (不在)区间查询 |
| [NOT] IN | (不在)IN 查询 |
**EQ** :等于(=)
例如:
```brush:vb
dict("post_id") = array("eq",3 )
'或者
dict("post_id") = array("=",3 )
```
和下面的查询等效
```brush:vb
dict("post_id") = 3
```
**NEQ**: 不等于(<>)
例如:
```brush:vb
dict("post_id") = array("neq",3)
'或者
dict("post_id") = array("<>",3)
'或者
dict("post_id") = array("!=",3)
```
**EGT**:大于等于(>=)
例如:
```brush:vb
dict("post_id") = array("egt",3)
'或者
dict("post_id") = array(">=",3)
```
**LT**:小于(<)
例如:
```brush:vb
dict("post_id") = array("lt",3)
'或者
dict("post_id") = array("<",3)
```
**ELT**:小于(<=)
例如:
```brush:vb
dict("post_id") = array("elt",3)
'或者
dict("post_id") = array("<=",3)
```
**[NOT] LIKE**: 同sql的LIKE
例如:
```brush:vb
dict("title") = array("like","测试%" )
```
查询条件就变成 `title LIKE '测试%' `
**[NOT] BETWEEN** :同sql的[not] between, 查询条件支持字符串或者数组,例如:
```brush:vb
dict("post_id") = array("not between","5,15" )
```
查询条件就变成 `post_id NOT BETWEEN 1 AND 15`
和下面的等效:
```brush:vb
dict("post_id") = array("not between",array(5,15) )
```
**[NOT] IN**: 同sql的[not] in ,查询条件支持字符串或者数组,例如:
```brush:vb
dict("post_id") = array("in","1,3,5,7" )
```
查询条件就变成 `post_id IN (1,3,5,7)`
和下面的等效:
```brush:vb
dict("post_id") = array("not between",array(1,3,5,7) )
```
**EXP**:表达式,支持更复杂的查询情况
例如:
```brush:vb
dict("post_id") = array("in","1,3,5,7" )
```
可以改成:
```brush:vb
dict("post_id") = array("exp", " in (1,3,5) " )
```
exp查询的条件不会被当成字符串,所以后面的查询条件可以使用任何SQL支持的语法,包括使用函数和字段名称。
### 三、使用数组作为查询条件
例如:
```brush:vb
array( "post_id > 15" , "is_top = true")
```
查询条件就变成 `post_id > 15 OR is_top = true `
须注意的是,数组每个元素之间生成的逻辑关系为OR
### 复合查询
利用数组元素之间的OR关系与Dictionary元素之间的AND关系可以组成更为复杂的复合查询
例如:
```brush:vb
set dict1 = D_
set dict2 = D_
dict1("post_id") = array("between","5,10")
dict1("title") = array("like","测试%")
dict2("post_id") = array("not between","5,10")
dict2("title") = array("like","%标题%")
arr = array( dict1 , dict2)
```
查询条件就变成 `( post_id BETWEEN 5 AND 10 AND title LIKE '测试%' ) OR ( post_id NOT BETWEEN 5 AND 10 AND title LIKE '%标题%' )`
### 统计查询
在应用中我们经常会用到一些统计数据,例如当前所有(或者满足某些条件)的用户数、所有用户的最大积分、用户的平均成绩等等,POPASP为这些统计操作提供了一系列的内置方法,包括:
| 方法 | 说明 |
| -------- | ----- |
| Count | 统计数量,无参数 |
| Max | 获取最大值,参数是要统计的字段名(必须) |
| Min | 获取最小值,参数是要统计的字段名(必须) |
| Avg | 获取平均值,参数是要统计的字段名(必须) |
| Sum | 求和,参数是要统计的字段名(必须) |
用法示例。
获取文章数:
```brush:vb
postCount = B_("post").count()
```
获取最大浏览次数:
```brush:vb
maxViews = B_("post").max("views")
```
获取被浏览过文章的最小浏览次数:
```brush:vb
minViews = B_("post").where("views>0").min("views")
```
获取平均浏览次数:
```brush:vb
avgViews = B_("post").avg("views")
```
获取浏览次数的总计:
```brush:vb
sumViews = B_("post").sum("views")
```
并且所有的统计查询均支持连贯操作的使用。
### 定位查询
POPASP支持定位查询,可以使用getN方法直接返回查询结果中的某个位置的记录(Dictionary)。例如:
获取符合条件的第3条记录:
```brush:vb
set dict = B_("post").order("post_id asc").getN(2)
```
获取符合条件的最后第二条记录:
```brush:vb
set dict = B_("post").order("post_id asc").getN(-2)
```
获取第一条记录:
```brush:vb
set dict = B_("post").order("post_id asc").First()
```
获取最后一条记录:
```brush:vb
set dict = B_("post").order("post_id asc").Last()
```