SELECT
字段,
字段2 AS 别名,
函数(字段3) AS 别名
FROM
表名
WHERE -- 行过滤条件
条件 AND
条件2
GROUP BY -- 分组字段
字段,
字段2
HAVING -- 组过滤条件
条件,
条件2
ORDER BY
字段 ASC, -- 升序(倒金字塔)
字段2 DESC -- 降序(正金字塔)
OFFSET
索引
LIMIT
数量
sql server中,LIMIT OFFSET等于OFFSET 索引 ROWS FETCH NEXT 数量 ROWS ONLY
CROSS JOIN,返回笛卡尔积,下面两句等价
SELECT * FROM 表1, 表2
SELECT * FROM 表1 CROSS JOIN 表2
INNER JOIN,等价于JOIN,返回两个表共有的行,若条件不符合,则排除该行
SELECT
*
FROM
表1
INNER JOIN
表2 ON 表1.字段 = 表2.字段
LEFT JOIN,返回表1的所有行,若表2有该行,则返回表2的行,若没有,则返回NULL
注:与之相反的是RIGHT JOIN,以右表为基准
SELECT
*
FROM
表1
LEFT JOIN
表2 ON 表1.字段 = 表2.字段
即查询中还有查询,比如在FROM里
SELECT
t.a AS a -- AS关键字可省略
FROM (
SELECT
a
FROM
t1
) AS t -- AS关键字可省略
注:实战中不推荐省略AS关键字
也可以在查询字段中,只要求结果是单个值
SELECT
a,
(
SELECT
b
FROM
t2
WHERE
t1.a = t2.a
LIMIT 1
) AS b
FROM
t1
注:上面查询可以用JOIN替换
如果要使用很多表,可以使用公用表表达式 公用表表达式用于增加维护性
WITH t AS ( -- 公用表表达式,在SELECT后被销毁
SELECT
b
FROM
t1
)
SELECT
*
FROM
t
表可以用在WHERE和HAVING中
SELECT
*
FROM
t1
WHERE
a IN (SELECT a FROM t2)
用于与其他行进行比较,比如排名
比如获取分数排名,这会按照分数排序,然后返回排名(即通过排序加获取行号排名)
SELECT
name,
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students;
如果要排特定的行,比如班级内排名
SELECT
name,
score,
class,
ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC) AS row_num
FROM students;
此外括号内除了PARTITION BY和ORDER BY外,还有框架边界关键字
function_name() OVER (
[PARTITION BY partition_expression, ...]
[ORDER BY sort_expression [ASC | DESC], ...]
[frame_clause]
)
frame_clause:
{ROWS | RANGE}
{frame_start | BETWEEN frame_start AND frame_end}
frame_start, frame_end:
UNBOUNDED PRECEDING
| value PRECEDING
| CURRENT ROW
| value FOLLOWING
| UNBOUNDED FOLLOWING
SUM,AVG等函数也能用在窗口函数中,作用是将前面的行进行计算,比如SUM在第五行会求前面几行加自己的和
但具体行为会受PARTITION BY和框架子句影响
去重
SELECT DISTINCT name FROM students;
条件控制
SELECT
name,
salary,
CASE
WHEN salary > 50000 THEN '高薪'
WHEN salary > 30000 THEN '中薪'
ELSE '低薪'
END AS salary_level
FROM employees;
返回列中第一个非NULL值
SELECT COALESCE(phone, email, '无联系方式') FROM contacts;
如果两个值相等则返回NULL
SELECT NULLIF(actual_value, expected_value) FROM test_results;
合并结果集并去重
SELECT name FROM employees WHERE department = 'IT'
UNION
SELECT name FROM contractors WHERE department = 'IT';
合并结果集不去重
SELECT name FROM employees
UNION ALL
SELECT name FROM contractors;
返回两个查询的交集
SELECT name FROM employees
INTERSECT
SELECT name FROM customers;
返回第一个查询有但第二个查询没有的结果
SELECT name FROM employees
EXCEPT
SELECT name FROM terminated_employees;
没什么,只有BEGIN、COMMIT和ROLLBACK,和SAVEPOINT、RELEASE SAVEPOINT