最近发现where后面还能跟if,前面mysql算是白学了。
WHERE IF(expression ,expr_true, expr_false);
MySQL的IF()函数,接受三个表达式,如果第一个表达式为true,而不是零且不为NULL,它将返回第二个表达式。否则,它返回第三个表达式。根据使用它的上下文,它返回数字或字符串值。
没错,跟java的三元表达式如出一辙
假如现需要 返回id大于3的王2,id小于等于3的王3
SQL语句可以这样写
SELECT * FROM users WHERE IF(id > 3, name = '王2', name = '王3');
返回结果
再比如现需要 返回id大于3的王2,id小于等于3的全部
SQL语句可以改为
SELECT * FROM users WHERE IF(id > 3, name = '王2', true);
运行结果
ps:下面是我项目中出现的一些问题,感兴趣的可以了解一下。我使用的go语言的gorm包演示,sql是一样的,都可以看
后端接收筛选数据,需要判断哪些字段为空,从而更改查询结果。
最容易想到的,也是最暴力的就是在接收数据时,写一堆if语句,判断哪些为空,从而调用哪些sql语句。
但这样有一个很明显的问题,就是if条件会非常的多,mysql语句也需要写很多,代码十分的冗余。
比如我现在定义一个结构体
// ParamScreen 筛选参数
type ParamScreen struct {
Gender string `json:"gender"`
State uint64 `json:"state"`
Name string `json:"name"`
}
这是关于State字段的一些需求,这里还是没有考虑Gender、和Name字段
筛选结果
默认全部已报名1
已宣讲2 已面试3 已录取4
待宣讲5(正处于1) 待面试6(正处于2) 待录取7(正处于3)
State字段在数据库中对应数据为
0已注册 1已报名 2已宣讲 3已面试 4已录取
所以上面的筛选结果在不考虑State、Gender、Name是否为空的情况下可以分为两部分
State <= 4时: state查询条件为 state>=
State > 4时: state查询条件为 state =
另外需要判断各字段是否为空,共有3×2×2种组合,但是通过IF可以简化为下面两种
// ScreenStudents 筛选学生
func ScreenStudents(per *models.ParamScreen) ([]*models.Student, error) {
/*筛选结果
默认全部已报名1
已宣讲2 已面试3 已通知4
待宣讲5(正处于1) 待面试6(正处于2) 待通知7(正处于3)
*/
var data []*models.Student
var err error
if per.State <= 4 {
err = DB.Where("IF (? = '',true,gender = ?) AND IF (? = '',true,state >= ?) AND IF (? = '',true,name like ?)", per.Gender, per.Gender, per.State, per.State, per.Name, "%"+per.Name+"%").Find(&data).Error
} else {
err = DB.Where("IF (? = '',true,gender = ?) AND IF (? = '',true,state = ?) AND IF (? = '',true,name like \"%?%\")", per.Gender, per.Gender, per.State, per.State, per.Name, "%"+per.Name+"%").Find(&data).Error
}
return data, err
}
真的是,太好用了!
上面把问题搞复杂了!!!
因为where 字段 like '%%'
就会查找该字段的所有值,不需要判断是否为空,比如上面的例子可以写成
// ScreenStudents 筛选学生
func ScreenStudents(per *models.ParamScreen) ([]*models.Student, error) {
/*筛选结果
默认全部已报名1
已宣讲2 已面试3 已通知4
待宣讲5(正处于1) 待面试6(正处于2) 待通知7(正处于3)
*/
var data []*models.Student
var err error
if per.State <= 4 {
err = DB.Where("gender = ? AND state >= ? AND name like ?", per.Gender, per.State, "%"+per.Name+"%").Find(&data).Error
} else {
err = DB.Where("gender = ? AND state = ? AND name like ?",per.Gender, per.State, "%"+per.Name+"%").Find(&data).Error
}
return data, err
}