SQL99及子查询
1.SQL99语法
outer 关键字可省略。
1.1 内连接
// 获取工资在10000-20000之间的员工薪水和等级
SELECT e.salary, j.j_level
FROM employees e
INNER JOIN joblevel j
ON e.salary BETWEEN 10000 AND 20000;
1.2 外连接
// 左外连接,左侧表作为主表,右侧表作为从表。与右外连接相反,二者可以转换。
// 获取所有女生的男朋友姓名,没有男朋友的就用NULL代替boy.name栏。
SELECT girl.name, boy.name
from girl
LEFT OUTER JOIN boy
ON girl.boyfriend_id = boy.id;
// 其它
right outer join
cross join
2.子查询
2.1 IN、NOT IN
// IN:在其中,NOT IN:不在其中。
// 查询location_id是14,17的部门全部员工名。
SELECT empName
FROM employees
WHERE dept_id
IN(
// 查找location_id是14,17的全部部门。
SELECT DISTINCT dept_id
FROM depts
WHERE location_id IN(14,17)
);
2.2 ANY,ALL、MAX、MIN、<>(!=)
‘任一’ 不是 ‘任意’,中华汉字博大精深。我迷了~
// 查找工资比job_name='IT_PROG'的任一工资低的员工信息。
SELECT *
FROM employees
WHERE salary < (
SELECT MAX(salary)
FROM employees
WHERE job_name = 'IT_PROG'
)
AND job_name <> 'IT_PROG';
// 等价写法
SELECT *
FROM employees
WHERE salary < ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_name = 'IT_PROG'
)
AND job_name <> 'IT_PROG';
2.3 连接查询转子查询
/* 查找每个部门员工数。(论如何把简单问题复杂化...草) */
-- 不包含为零的专业
SELECT d.id,count(1)
FROM depts d
INNER JOIN employees e
ON d.id = e.dept_id
GROUP BY d.id;
# 不包含为零的专业的等价子查询写法
SELECT d.id,(
SELECT COUNT(1)
FROM employees e
ON e.dept_id = d.id
)
FROM depts d;
// 解释:从职业表中查询,但是还不知到查找啥,根据select中条件确定。
// 而select中又是根据emp中的雇员dept_id查找的,自然找不到没有人的部门。
// 至于前面的d.id怎么处理·猜测·是根据括号中使用到的部分确定的。
-- ——————————————————————卡哇伊分割线———————————————————————
-- 包含为零的专业
SELECT d.id,count(e.id)
FROM depts d
LEFT OUTER JOIN employees e
ON d.id = e.dept_id
GROUP BY d.id;
# 包含为零的专业,等价子查询写法
SELECT d.id,(
SELECT COUNT(1)
FROM employees e
ON e.dept_id = d.id
)
FROM depts d
GROUP BY d.id;
// 解释:因为先执行group by语句,学生数为0专业已经分出来了。之后执行select语句,没有dept_id相等的学生,count为0。
2.4 EXISTS、IN
// exists应该被独立看成一个表达式。比如下面的句子中exists后面的语句代表一个值。
-- 查询有员工的部门名。
SELECT dept_name
FROM depts d
WHERE EXISTS(
SELECT * FROM employees e
WHERE e.dept_id = d.id
);
庄周晓梦迷蝴蝶,望帝春心托杜鹃。——李商隐