含义:又称多表连接,在没有特定条件限制时,单查询的字段来自多个表时,结果有mn种,故称笛卡尔乘积现象
例:SELECT
FROM beauty,boys;
解决方案:

  • 添加有效连接条件(找两张表中相匹配的东西)
  • SELECT * FROM beauty,boys WHERE beauty.boyfriend_id = boys.id;

条件分类:

  • 按年代分类

1、sql92标准(仅支持内连接)
2、sql99标准(支持内连接、外连接(左外和右外)、交叉连接)

  • 按功能分类

1、内连接
等值连接
非等值连接
自连接
2、外连接
左外连接
右外连接
全外来连接(mysql不支持)
3、交叉连接


SQL92语法:

格式:SELECT 查询列表
FROM 表1 别名,表2 别名
WHERE 表1.key=表2.key
(AND 筛选条件)
(GROUP BY 分组字段)
(HAVING 分组后的筛选)
(ORDER BY 排序字段)

起别名:用于提高语句简洁度,区分多个重名字段(起别名后,不能用表命,而是要用别名)

1、等值连接:结果是多表的交集部分

  • SELECT e.last_name,e.job_id,job_title

FROM employees AS e,jobs AS j
WHERE e.job_id = j.job_id;

2、非等值连接:

  • SELECT salary,grade_level

FROM employees e,job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal;

3、自连接:来自同一个表的条件

  • SELECT e.employee_id,e.last_name,m.employee_id,m.last_name

FROM employees e,employees m
WHERE e.manager_id = m.employee_id;


SQL99语法:

格式:
SELECT 查询列表
FROM 表1 别名
(连接类型)JOIN 表2 别名
ON 条件
(WHERE 筛选条件)
(GROUP BY 分组)
(HAVING 筛选条件) 不可以使用别名
(ORDER BY 排序条件)

分类:
内连接:INNER JOIN ON 【连续写法,从后往前 on】
外连接:LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN
交叉连接:CROSS ON

1、内连接

  • SELECT city,COUNT(*) 部门个数FROM departments d

INNER JOIN locations l
ON d.location_id=l.location_id
GROUP BY city
HAVING COUNT(*)>3;

2、非等值连接

  • SELECT salary,grade_level

FROM employees e JOIN job_grades j ON e.salary
BETWEEN j.lowest_sal AND j.highest_sal;
3.自连接

  • SELECT e.last_name,m.last_name

FROM employees e JOIN employees m
ON e.department_id = m.department_id
WHERE e.last_name LIKE ‘%k%’;

4.外连接:用于查询两张表的匹配条件有缺失的情况
特点:
1、查询结果为主表中的所有记录
2、如果满足匹配条件则返回相应的值,否则返回NIULL
3、外连接查询结果为:内连接结果+主表中有而从表中没有的记录
4、左外连接:left join 左边的是主表
右外连接:right join 右边是主表
左外右外交换两个表的顺序,实现的效果一样
5、全外连接 = 内连接结果+主表有但从表没有的+从表有但主表没有的

  • SELECT b.name,bo.*

FROM beauty b LEFT OUTER JOIN boys bo
ON b.boyfriend_id = bo.id
WHERE b.id IS NULL;

  • SELECT b.name,bo.*

FROM boys bo RIGHT OUTER JOIN beauty b ON b.boyfriend_id=bo.id
WHERE b.id IS NULL;

  • FULL OUTER JOIN(mql不支持)

5、交叉连接:结果为笛卡尔乘积

  • SELECT b.,bo.FROM beauty b

CROSS JOIN boys bo;

image.png
image.png

模糊查询

1、%:表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
SELECT * FROM [user] WHERE u_name LIKE '%三%'
将会把u_name为“张三”,“张猫三”、“三脚猫”,“唐三藏”等等有“三”的记录全找出来

如果需要找出u_name中既有“三”又有“猫”的记录,请使用and条件##
SELECT * FROM [user] WHERE u_name LIKE '%三%' AND u_name LIKE '%猫%'

SELECT * FROM [user] WHERE u_name LIKE '%三%猫%'
虽然能搜索出“三脚猫”,但不能搜索出符合条件的“张猫三”

2、_: 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:

SELECT * FROM [user] WHERE uname LIKE ‘三_’
只找出“唐三藏”这样u_name为三个字且中间一个字是“三”的;

SELECT * FROM [user] WHERE u_name LIKE '三__';
只找出“三脚猫”这样name为三个字且第一个字是“三”的;

3、[ ]:表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。

SELECT * FROM [user] WHERE u_name LIKE '[张李王]三'
将找出“张三”、“李三”、“王三”(而不是“张李王三”);

如 [ ] 内有一系列字符(01234、abcde之类的)则可略写为“0-4”、“a-e”
SELECT * FROM [user] WHERE u_name LIKE '老[1-9]'
将找出“老1”、“老2”、……、“老9”;

4、[^ ] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。

SELECT * FROM [user] WHERE u_name LIKE '[^张李王]三'
将找出不姓“张”、“李”、“王”的“赵三”、“孙三”等;

SELECT * FROM [user] WHERE u_name LIKE '老[^1-4]';
将排除“老1”到“老4”,寻找“老5”、“老6”、……

5、查询内容包含通配符时
由于通配符的缘故,导致我们查询特殊字符“%”、“_”、“[”的语句无法正常实现,而把特殊字符用“[ ]”括起便可正常查询。据此我们写出以下函数:

  1. function sqlencode(str)
  2. str=replace(str,"[","[[]") '此句一定要在最前
  3. str=replace(str,"_","[_]")
  4. str=replace(str,"%","[%]")
  5. sqlencode=str
  6. end function