MySQL查询语句WHERE后面IF判断及应用

MySQL查询语句WHERE后面IF判断及应用

最近发现where后面还能跟if,前面mysql算是白学了。
WHERE IF(expression ,expr_true, expr_false);
MySQL的IF()函数,接受三个表达式,如果第一个表达式为true,而不是零且不为NULL,它将返回第二个表达式。否则,它返回第三个表达式。根据使用它的上下文,它返回数字或字符串值。
没错,跟java的三元表达式如出一辙

IF的使用

假如现需要 返回id大于3的王2,id小于等于3的王3
MySQL查询语句WHERE后面IF判断及应用_第1张图片
SQL语句可以这样写

SELECT * FROM users WHERE IF(id > 3, name = '王2', name = '王3');

返回结果
MySQL查询语句WHERE后面IF判断及应用_第2张图片
再比如现需要 返回id大于3的王2,id小于等于3的全部
SQL语句可以改为

SELECT * FROM users WHERE IF(id > 3, name = '王2', true);

运行结果
MySQL查询语句WHERE后面IF判断及应用_第3张图片
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
}

你可能感兴趣的:(mysql,数据库,golang)