PythonLearn

SQL查询语法

基础

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 BYORDER 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;

事务语句

没什么,只有BEGINCOMMITROLLBACK,和SAVEPOINTRELEASE SAVEPOINT