MySql怎么实现多条件查询呢?我有五种条件。关键是我想知道查询语句该怎么精简。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql怎么实现多条件查询呢?我有五种条件。关键是我想知道查询语句该怎么精简。相关的知识,希望对你有一定的参考价值。

有的方法用是数组。不知道怎么写。。。

给你思路,具体你自己去写:
1.你这个是有二类条件:必选的:前二个2选1;
后面三个条件是可选的,选全部等于没选就没必要加这个条件,关键字没填的话等同;
所以你其实就是1-4个条件。
2.实现建议用存储过程,参数根据实际情况传递,条件越多查询越慢,越慢(耗cpu和io)的条件要放在语句的最后。
参考技术A 如果是php,建议使用ThinkPHP框架吧。
$where['condition1']=$_POST['condition1'];
$where['condition2']=$_POST['condition2'];
$where['condition3']=$_POST['condition3'];
$where['condition4']=$_POST['condition4'];
$where['condition5']=$_POST['condition5'];
$aa=M('Aa');
$aa->where($where)->select();

Mysql数据库操作总结

目录

常用操作

起别名

去重

字符串拼接

排序

条件查询

条件运算符

逻辑运算符

模糊查询

like关键字与通配符

转义字符

between and关键字

in关键字

is null 和 is not null 关键字

分组查询

简单使用

分组前添加筛选条件

分组后添加筛选条件 

以函数为分组条件 

按多字段分组

多表查询

 等值连接

非等值连接

自连接

外连接

左外连接

右外连接

全外连接

交叉连接

子查询

where后面的标量子查询

where后面的列子查询

where后面的行子查询

select 后面的子查询

from 后面的子查询

exists 后面的子查询

分页查询

联合查询

插入数据

基本使用

插入多行 

支持子查询 

修改数据

修改单表数据

修改多表数据

删除数据

单表删除

多表删除


常用操作

起别名

起别名时,如果别名有特殊字符,用双引号或者单引号将别名包括起来。(“别名”)

SELECT 
  字段名 AS 别名 
FROM
  表名 ;

去重

去重关键字:distinct。

SELECT DISTINCT 
  字段名
FROM
  表名 ;

字符串拼接

concat(字段名A,字段名B)

SELECT 
  CONCAT(字段名, 字段名) 
FROM
  表名 ;

查询结果为两个字段查询的结果拼接在一起

排序

order by 字段名 (asc或者desc)

asc表示升序排序,desc表示降序排序,默认是升序排序。同时Mysql的排序支持多关键字排序,也就是说,某一个字段的内容相同,可以在此基础上用另一个字段进行再排序。

SELECT 
  字段名 
FROM
  表名 
ORDER BY 字段名 DESC ;

多字段排序

SELECT 
 字段名 
FROM
  表名 
ORDER BY 字段名A ASC,字段名B ASC ;

条件查询

条件运算符

大于:> ,小于:< ,等于: = ,不等于: != 或者用 <>,大于等于: >= ,小于等于: <=

逻辑运算符

与逻辑: && 或者用 and,或逻辑: || 或者用 or,非逻辑: ! 或者用 not

SELECT 
  * 
FROM
  表名 
WHERE salary > 12000 
  AND salary < 120000 
  AND last_name = '小红' ;

模糊查询

like关键字与通配符

%通配符:匹配任意多个字符,包含0个字符。

_通配符:匹配单个字符。

在表中查询名字中第三个字符为e,以字符a结尾的人的信息

SELECT 
  * 
FROM
  employees 
WHERE first_name LIKE '__e%a' ;

转义字符

如果我们要模糊查询字段内容中包含%、_通配符的信息时,要使用转义字符进行转移。

默认转义字符:\\

指定转义字符:ESCAPE '指定的转义字符'

下面两句查询语句效果是相同的

SELECT 
  * 
FROM
  employees 
WHERE last_name LIKE '_$_%' ESCAPE '$' ;


SELECT 
  * 
FROM
  employees 
WHERE last_name LIKE '_\\_%' ;

between and关键字

使用between and 关键字进行查询,表示某字段的值在这一范围内,并且包含边界值。

例:查询员工id在100到200区间内的员工信息。(包含100和200)

SELECT 
  * 
FROM
  employees 
WHERE employee_id BETWEEN 100 
  AND 200 ;

in关键字

使用in关键字进行查询,表示某字段的值是否在in列表当中。in列表当中的值必须类型一致或者兼容,例如 '100' 和 100 就是兼容的。

例:查询名字在in列表当中的数据

SELECT 
  * 
FROM
  employees 
WHERE last_name IN ('Kochhar', 'De Haan') ;

is null 和 is not null 关键字

顾名思义,is null 就是查询某字段为null,is not null 就是查询某字段不为null。在Mysql数据库当中,判断等于null不能直接使用等号来进行判断。

例:查询条件为某字段为null

SELECT 
  * 
FROM
  employees 
WHERE commission_pct IS NULL ;

例:查询条件为某字段不为null

SELECT 
  * 
FROM
  employees 
WHERE commission_pct IS NOT NULL ;

分组查询

简单使用

下面的sql语句可以理解为,查询出job_id,然后按照job_id进行分组,分别得到每一组的最大工资。

SELECT 
  MAX(salary),
  job_id 
FROM
  employees 
GROUP BY job_id ;

分组前添加筛选条件

分组前添加筛选条件使用where,将查询到的结果再进行分组。

SELECT 
  MAX(salary) AS 最高工资,
  job_id 
FROM
  employees 
WHERE email LIKE '%a%' 
GROUP BY job_id ;

分组后添加筛选条件 

分组后添加筛选条件用having,将分组后的数据再筛选。

SELECT 
  MAX(salary) AS 最高工资,
  job_id 
FROM
  employees 
WHERE email LIKE '%a%' 
GROUP BY job_id 
HAVING 最高工资 > 10000 ;

以函数为分组条件 

可以以函数来当作分组的条件。

下面的查询就是以名字的长度来进行分组

SELECT 
  MAX(salary) AS 最高工资,
  LENGTH(last_name) AS 长度 
FROM
  employees 
WHERE email LIKE '%a%' 
GROUP BY 长度 
HAVING 最高工资 > 10000 ;

按多字段分组

下面的sql语句将查询结果按照部门id和工种id进行分组,部门id和工种id相同的分为一组。

SELECT 
  AVG(salary) 平均工资,
  department_id 部门id,
  job_id 工种id 
FROM
  employees 
GROUP BY 部门id,
  工种id 
ORDER BY 平均工资 ;

多表查询

当查询的字段来自多个表时,就需要使用多表查询

 等值连接

按照字段的内容进行连接

下面的sql语句从两个表中查找数据,将beauty表中的boyfriend_id字段和boys表中id字段进行连接。

SELECT 
  `name`,
  boyName 
FROM
  boys,
  beauty 
WHERE beauty.boyfriend_id = boys.id ;

如果有查询的不同表之间存在字段名相同的情况,我们就需要用表名来限定字段。

下面的sql语句对表名取别名,通过表名来限定字段,对表名取了别名之后,不能再用原表名来限定字段。  

SELECT 
  emp.last_name,
  emp.job_id,
  job.job_title 
FROM
  employees emp,
  jobs job 
WHERE emp.`job_id` = job.`job_id` ;

上面的sql语句标准为sql92,我们还可以参照sql99的标准写成如下形式,效果相同,语法不同。

SELECT 
  emp.last_name,
  emp.job_id,
  job.job_title 
FROM
  employees emp 
  INNER JOIN jobs job 
    ON emp.`job_id` = job.`job_id` ;

 多个表联合查询时,只需要添加 inner join 表名 on 连接条件  即可。

非等值连接

下面的sql语句连接条件是一个范围,根据工资的范围显示工资的等级。

SELECT 
  emp.last_name,
  emp.job_id,
  job.grade_level 
FROM
  employees emp,
  job_grades job 
WHERE emp.`salary` BETWEEN job.`lowest_sal` 
  AND job.`highest_sal` ;

sql99标准写法如下:

SELECT 
  emp.last_name,
  emp.job_id,
  job.grade_level 
FROM
  employees emp 
  INNER JOIN job_grades job 
    ON emp.`salary` BETWEEN job.`lowest_sal` 
    AND job.`highest_sal` ;

自连接

顾名思义,就是当前表自己和自己连接在一起

例:下面的sql语句将自己表中的员工信息和上级信息连接在一起,自连接时,由于是在同一张表中查询,需要给表设置别名,这样才能区分查询的字段。

SELECT 
  员工.`employee_id` 员工id,
  员工.`last_name` 员工名,
  上级.`employee_id` 上级id,
  上级.`last_name` 上级名 
FROM
  employees 员工,
  employees 上级 
WHERE 员工.`manager_id` = 上级.`employee_id` ;

sql99标准写法如下:

SELECT 
  员工.`employee_id` 员工id,
  员工.`last_name` 员工名,
  上级.`employee_id` 上级id,
  上级.`last_name` 上级名 
FROM
  employees 员工 
  INNER JOIN employees 上级 
    ON 员工.`manager_id` = 上级.`employee_id` ;

外连接

外连接查询结果为主表中的所有记录,如果从表当中有匹配的数据,就显示匹配的值,否则显示null。

左外连接

left  (outer)  join 表名 on 连接条件

以左边的表为主表,右边的表为从表建立连接

SELECT 
  b1.`name`,
  b1.`boyfriend_id`,
  b2.`id`,
  b2.`boyName` 
FROM
  beauty b1 
  LEFT OUTER JOIN boys b2 
    ON b1.`boyfriend_id` = b2.`id` ;

右外连接

right  (outer)  join 表名 on 连接条件

以右边的表为主表,左边的表为从表建立连接

SELECT 
  b1.`name`,
  b1.`boyfriend_id`,
  b2.`id`,
  b2.`boyName` 
FROM
  beauty b1 
  RIGHT OUTER JOIN boys b2 
    ON b1.`boyfriend_id` = b2.`id` ;

全外连接

Mysql不支持这种形式

全外连接查询结果=内连接结果+表1中有但是表2中没有的+表2中有但是表1中没有的

交叉连接

cross join 表名

查询结果为两个表的笛卡尔乘积

SELECT 
  * 
FROM
  beauty b1 
  CROSS JOIN boys b2 ;

子查询

出现在语句内部的select语句,称为子查询或内查询,查询语句内部嵌套了其他select语句的查询称为外查询或主查询。

按结果集的行列数不同划分如下:

标量子查询:结果集一行一列

列子查询:结果集一列多行

行子查询:结果集一行多列

表子查询:结果集一般为多行多列

where后面的标量子查询

子查询的结果为一行一列并且放在where后面

下面的sql语句查询工种和员工id141的员工相同,并且工资大于员工id为143的人的信息

SELECT 
  last_name,
  job_id,
  salary 
FROM
  employees 
WHERE job_id = 
  (SELECT 
    job_id 
  FROM
    employees 
  WHERE employee_id = 141) 
  AND salary > 
  (SELECT 
    salary 
  FROM
    employees 
  WHERE employee_id = 143) 
ORDER BY salary DESC ;

where后面的列子查询

操作符:

in/not in :等于或不等于列表中的任意一个。

any/some:两个关键字达到的效果相同,都是和子查询的结果的某一个值进行比较,满足其中一个条件即可。

all:和子查询的结果的所有值进行比较,满足所有条件才行。

使用in/not in,查询location_id是1400或1700的部门中的所有员工姓名

SELECT 
  last_name 
FROM
  employees 
WHERE department_id IN 
  (SELECT DISTINCT 
    department_id 
  FROM
    departments 
  WHERE location_id IN (1400, 1700)) ;

使用any/some,查询其他工种中比job_id为IT_PROG任一工资低的员工的员工号、姓名、job_id以及salary。

SELECT 
  last_name,
  employee_id,
  job_id,
  salary 
FROM
  employees 
WHERE salary < ANY 
  (SELECT DISTINCT 
    salary 
  FROM
    employees 
  WHERE job_id = 'IT_PROG') 
  AND job_id != 'IT_PROG' ;

使用any/some代码可读性不高,我们通常采用如下写法达到相同的效果。因为any是满足一个条件即可,那么可以写作小于查询结果集中最高工资。

SELECT 
  last_name,
  employee_id,
  job_id,
  salary 
FROM
  employees 
WHERE salary < 
  (SELECT DISTINCT 
    MAX(salary) 
  FROM
    employees 
  WHERE job_id = 'IT_PROG') 
  AND job_id != 'IT_PROG' ;

使用all,查询其他部门中比job_id为IT_PROG的部门所有工资都低的员工的员工号、姓名、job_id以及salary。

SELECT 
  last_name,
  employee_id,
  job_id,
  salary 
FROM
  employees 
WHERE salary < ALL 
  (SELECT DISTINCT 
    salary 
  FROM
    employees 
  WHERE job_id = 'IT_PROG') 
  AND job_id != 'IT_PROG' ;

all代码可读性也不高,由于all是要满足所有的条件,那么可以用min函数来简化。

SELECT 
  last_name,
  employee_id,
  job_id,
  salary 
FROM
  employees 
WHERE salary < 
  (SELECT DISTINCT 
    MIN(salary) 
  FROM
    employees 
  WHERE job_id = 'IT_PROG') 
  AND job_id != 'IT_PROG' ;

where后面的行子查询

查询员工编号最小并且工资最高的员工信息

通过标量子查询能够达到上面的要求

SELECT 
  * 
FROM
  employees 
WHERE employee_id = 
  (SELECT 
    MIN(employee_id) 
  FROM
    employees) 
  AND salary = 
  (SELECT 
    MAX(salary) 
  FROM
    employees) ;

上面的代码略显重复,我们可以通过行子查询来简化。 

SELECT 
  * 
FROM
  employees 
WHERE (employee_id, salary) = 
  (SELECT 
    MIN(employee_id),
    MAX(salary) 
  FROM
    employees) ;

select 后面的子查询

子查询位于select后面的,仅仅支持标量子查询(即一行一列)。

将子查询语句直接写在select后面,下面的sql语句查询部门id和员工个数,select后面的子查询一般可以用其他的方式代替,并且效率更高。

SELECT 
  department_id,
  (SELECT 
    COUNT(*) 
  FROM
    employees e 
  WHERE e.department_id = d.department_id) AS 员工个数 
FROM
  departments d ;

from 后面的子查询

下面的sql语句查询每个部门的平均工资的工资等级,相当于将from后面的子查询语句的结果当作了一个表,然后和job_grades表进行连接。

SELECT 
  ag_dep.*,
  job.`grade_level` 
FROM
  (SELECT 
    AVG(salary) ag,
    department_id 
  FROM
    employees 
  GROUP BY department_id) ag_dep 
  INNER JOIN job_grades job 
    ON ag_dep.ag BETWEEN lowest_sal 
    AND highest_sal ;

exists 后面的子查询

这种查询不常用,了解即可。并且这种查询的功能可以用前面其他的查询方式代替,并且可读性更高。

查询结果为1或者0,当exists后面的子查询有值时为1,查询结果为空时为0.

下面的sql语句查询是否有员工的工资大于30000

SELECT 
  EXISTS 
  (SELECT 
    employee_id 
  FROM
    employees 
  WHERE salary = 30000) ;

分页查询

limit A , B : 从第A条数据开始往后数B条数据返回,索引从0开始计算。

接下来的sql语句查询从第1条数据开始往后数5条数据。(即前五条数据)

SELECT 
  * 
FROM
  employees 
LIMIT 0, 5 ;

联合查询

查询的结果来自于多个表,且多个表之间没有直接的连接关系,但查询的信息一致时,就要使用联合查询。

使用联合查询注意事项:

1.多条查询语句的查询列数是一致的。

2.多条查询语句查询的每一列的类型和内容最好顺序一致。

3.union关键字默认去重,要显示全部的数据用union all。

SELECT 
  id,
  cname,
  csex 
FROM
  t_ca 
WHERE csex = '男' 
UNION
#union all
SELECT 
  t_id,
  tName,
  tGender 
FROM
  t_ua 
WHERE tGender = 'male' ;

插入数据

基本使用

字段名和数据要对应,顺序可以调换,可以为null的字段可以插入null。

INSERT INTO 表名 (字段名1, 字段名2, ...) VALUE (数据1, 数据2, ...) ;

可以省略列名,默认插入所有列,而且列的顺序和表中列的顺序一致。

INSERT INTO 表名 VALUE (数据1, 数据2, ...) ;

插入多行 

 可以插入多行数据,用逗号分隔开即可。

INSERT INTO 表名 (字段名1, 字段名2, ...) VALUE (数据1, 数据2, ...),
(数据1 .1, 数据2 .1, ...),
(数据3 .1, 数据3 .1, ...) ;

支持子查询 

 支持子查询,可以将查询得到的数据插入进表中。注意格式、类型、长度的统一。

INSERT INTO 表名 (字段名1, 字段名2, ...) 
SELECT 
  字段名A,
  字段名B,
  ...
FROM
  表2 ;

修改数据

修改单表数据

UPDATE 
  表名 
SET
  字段名1 = 新值,
  字段名2 = 新值 
WHERE 筛选条件 ;

修改多表数据

 修改多表的数据和查询类似,先连接不同的表,相当于建立了一个虚拟的表,再根据条件修改这个虚拟的表。

UPDATE 
  表1 别名1 
  INNER|left|right JOIN 表2 别名2 
    ON 连接条件 SET 字段名 = 新值 
WHERE 筛选条件 ;

删除数据

单表删除

DELETE 
FROM
  表名 
WHERE 筛选条件 ;

truncate 全部删除,不能加where条件,删除效率比delete高。

使用truncate删除数据后,自增长列的值从1开始,而delete从断点开始。

truncate删除没有返回值,并且不能回滚。 

TRUNCATE TABLE 表名 ;

多表删除

DELETE 
  表1,
  表2 
FROM
  表1 
  INNER|left|right JOIN 表2 
    ON 连接条件 
WHERE 筛选条件 ;

以上是关于MySql怎么实现多条件查询呢?我有五种条件。关键是我想知道查询语句该怎么精简。的主要内容,如果未能解决你的问题,请参考以下文章

JSP+Servlet+javabean+mysql实现页面多条件模糊查询(转载)

用JS脚本如何实现多关键+多条件的查询(SQL语句)?

如何按条件查询MYSQL数据库中的表名

查询mysql两个条件 一个是等于 一个不等于 请问怎么写?

Mysql数据库操作总结

Excel vba 多个条件查询应该怎么做,可以用find方法吗?