(SQL学习随笔3)SQL语法——SELECT语句

这篇具有很好参考价值的文章主要介绍了(SQL学习随笔3)SQL语法——SELECT语句。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基本认识

SELECT 'test'; -- 查询单个值
SELECT 1, 2.3, 'test', true; -- 查询多个值
SELECT 1 AS 整数, 2.1 AS 浮点数, '测试' AS 字符串, true AS 布尔型; -- 针对每个查询到的值,在其后配合AS关键字设置别名
SELECT 1 + 2, 5 * 10, version() AS 版本信息; -- 查询函数或算式运算结果

FROM关键字

-- 创建示例数据表
CREATE TABLE tips
(
    total_bill FLOAT,
    tip        FLOAT,
    sex        CHAR(6),
    smoker     CHAR(3),
    day        CHAR(3),
    time       TEXT,
    size       INT
);

-- 插入示例数据
INSERT INTO tips
VALUES (16.99, 1.01, 'Female', 'No', 'Sun', 'Dinner', 2),
       (10.34, 1.66, 'Male', 'No', 'Sun', 'Dinner', 3),
       (21.01, 3.5, 'Male', 'No', 'Sun', 'Dinner', 3),
       (23.68, 3.31, 'Male', 'No', 'Sun', 'Dinner', 2),
       (24.59, 3.61, 'Female', 'No', 'Sun', 'Dinner', 4),
       (25.29, 4.71, 'Male', 'No', 'Sun', 'Dinner', 4),
       (8.77, 2.0, 'Male', 'No', 'Sun', 'Dinner', 2),
       (26.88, 3.12, 'Male', 'No', 'Sun', 'Dinner', 4),
       (15.04, 1.96, 'Male', 'No', 'Sun', 'Dinner', 2),
       (14.78, 3.23, 'Male', 'No', 'Sun', 'Dinner', 2);
SELECT * FROM tips;
SELECT tip, sex FROM tips;
SELECT tip AS 小费 FROM tips;

LIMIT与OFFSET

SELECT * FROM tips LIMIT 3; -- 查询前三行
SELECT * FROM tips LIMIT 3 OFFSET 8; -- 从第9行(包含)开始查询三行

ORDER BY

SELECT * FROM tips ORDER BY total_bill DESC; -- 单字段降序(默认升序)
SELECT * FROM tips ORDER BY size ASC, total_bill DESC; -- 多字段排序

WHERE条件查询

-- 示例数据
CREATE TABLE funds
(
    fund_code          VARCHAR(10) PRIMARY KEY,
    fund_name          TEXT,
    fund_type          TEXT,
    within_a_week      FLOAT,
    within_a_month     FLOAT,
    within_three_month FLOAT,
    within_this_year   FLOAT,
    within_six_month   FLOAT,
    within_one_year    FLOAT
);

INSERT INTO funds
VALUES ('5669', '前海开源公用事业股票', '股票型', 0.0714, 0.2844, 0.6162, 0.3708, 0.3582, 1.263),
       ('828', '泰达转型机遇', '股票型', 0.0328, 0.1904, 0.5942, 0.2832, 0.2827, 1.0693),
       ('689', '前海开源新经济混合', '混合型', 0.0769, 0.2797, 0.5918, 0.3768, 0.3504, 0.9222),

单值比较

= 等于
<> 不等于
<<= 小于、小于等于
>>= 大于、大于等于

SELECT * FROM funds WHERE fund_type <> '混合型';

多条件组合

SELECT * FROM funds 
WHERE fund_type <> '混合型' AND within_three_month > 0.5; -- AND

SELECT * FROM funds
WHERE fund_type = '股票型' OR fund_type = '债券型'; -- OR

SELECT * FROM funds
WHERE fund_type IN ('股票型', '债券型'); -- IN

SELECT * FROM funds
WHERE NOT fund_type IN ('股票型', '债券型'); -- NOT(加在完整条件之前)

范围筛选

SELECT * FROM funds
WHERE within_three_month BETWEEN 0.4 AND 0.5; -- BETWEEN ... AND ...

空值匹配

SELECT * FROM funds WHERE within_one_year = NULL; -- 这样不行

SELECT * FROM funds WHERE within_one_year IS NULL; -- 正确

LIKE通配

  • 主要有两种通配符——'%''_',其中'%'代表任意多个字符,'_'代表单个任意字符
SELECT * FROM funds WHERE fund_name LIKE '%新能源%';

SELECT * FROM funds WHERE fund_name LIKE '%a';
SELECT * FROM funds WHERE fund_name LIKE '%A'; -- 在MySQL中,与上面返回一致(不区分大小写)

SELECT * FROM funds WHERE BINARY fund_name LIKE '%A'; -- 强制当成二进制格式后通配

条件分组

SELECT * FROM funds
WHERE (fund_name LIKE '%医药%' AND within_three_month > 0.4)
   OR (fund_name LIKE '%车%' AND within_three_month > 0.45);

运算符和函数

数据变换

  • 文本处理

MySQL

/*
concat(字段1, 字段2, ... ,字段n)用于将传入的若干个【字段】或单个值信息拼接为新的单个字段
left(字段, 截取字符数量)用于从【字段】每条记录最左端开始提取【截取字符数量】个的字符
right(字段, 截取字符数量)用于从【字段】每条记录最右端开始提取【截取字符数量】个的字符
char_length(字段)用于计算传入【字段】每条记录的字符数量(单个汉字亦算作1个字符)
substr(字段, 开始位置, 截取长度)用于提取【字段】从【开始位置】往后最多【截取数量】个字符
regexp_like(字段, 正则表达式)用于判断【字段】中是否存在满足【正则表达式】模式子串,返回1表示存在,0表示不存在
replace(字段, 目标字符串, 替换字符串)用于将【字段】中所有【目标字符串】替换为【替换字符串】
repeat(字段, 重复次数)用于将【字段】复制【重复次数】后进行拼接
reverse(字段)用于将【字段】中每条字符记录进行翻转
*/
SELECT concat(fund_name, ' ', fund_type, ' ', within_a_month) AS 'concat()',
       left(fund_name, 2) AS 'left()',
       right(fund_name, 3) AS 'right()',
       char_length(fund_name) AS 'char_length()',
       substr(fund_name, 3, 4) AS 'substr()',
       regexp_like(fund_name, '医药') AS 'regexp_like()',
       replace(fund_name, '医药', 'medicine') AS 'replace()',
       repeat(fund_name, 3) AS 'repeat()',
       reverse(fund_name) AS 'reverse()'
FROM funds;

PostgreSQL

/*
concat(字段1, 字段2, ... ,字段n)用于将传入的若干个【字段】或单个值信息拼接为新的单个字段
left(字段, 截取字符数量)用于从【字段】每条记录最左端开始提取【截取字符数量】个的字符
right(字段, 截取字符数量)用于从【字段】每条记录最右端开始提取【截取字符数量】个的字符
char_length(字段)用于计算传入【字段】每条记录的字符数量(单个汉字亦算作1个字符)
substr(字段, 开始位置, 截取长度)用于提取【字段】从【开始位置】往后最多【截取数量】个字符
字段 ~ 正则表达式  用于判断【字段】中是否存在满足【正则表达式】模式子串,直接返回返回boolean型判断结果
replace(字段, 目标字符串, 替换字符串)用于将【字段】中所有【目标字符串】替换为【替换字符串】
repeat(字段, 重复次数)用于将【字段】复制【重复次数】后进行拼接
reverse(字段)用于将【字段】中每条字符记录进行翻转
*/
SELECT concat(fund_name, ' ', fund_type, ' ', within_a_month) AS "concat()",
       left(fund_name, 2) AS "left()",
       right(fund_name, 3) AS "right()",
       char_length(fund_name) AS "char_length()",
       substr(fund_name, 3, 4) AS "substr()",
       fund_name ~ '医药' AS "~",
       replace(fund_name, '医药', 'medicine') AS "replace()",
       repeat(fund_name, 3) AS "repeat()",
       reverse(fund_name) AS "reverse()"
FROM funds;

在PostgreSQL中还可以使用 || 来拼接若干个字符型字段:
SELECT fund_name || ' - ' || fund_type FROM funds;

  • 数值计算

PostgreSQL

SELECT 1 + 1 AS,
       1 - 2 AS,
       2 * 5 AS,
       4 / 3 AS 整数除法,
       4 / 3. AS 浮点数除法,
       2 ^ 2 AS 平方,
       |/ 25 AS 平方根,
       5 % 2.2 AS 取余,
       ||/ 27 AS 立方根,
       3! AS 阶乘,
       @ -5.5 AS 绝对值;

MySQL

SELECT 1 + 1 AS,
       1 - 2 AS,
       2 * 5 AS,
       4 / 3 AS 整数除法,
       4 / 3. AS 浮点数除法,
       5 % 2.2 AS 取余,
       sqrt(9) AS 平方根,
       abs(-5.5) AS 绝对值;
  • 聚合函数
SELECT min(within_three_month) AS 最小值,
       max(within_three_month) AS 最大值,
       avg(within_three_month) AS 平均值,
       count(fund_type) AS 计算行数,
       sum(within_three_month) AS 求和
FROM funds;

SELECT DISTINCT fund_type FROM funds; -- 去重
SELECT count(DISTINCT fund_type) FROM funds; -- 统计不重复字段的数量

分组运算

SELECT fund_type, count(*) AS 基金数量, avg(within_a_month) AS 最近一个月平均涨幅 -- 这些字段运算后必须是和分组字段等长的,即对非分组字段进行的运算操作一定是聚合压缩操作
FROM funds
GROUP BY fund_type
ORDER BY 最近一个月平均涨幅 DESC
LIMIT 3;
  • 分组后过滤(HAVING)
SELECT fund_type, count(*) AS 基金数量, avg(within_a_month) AS 最近一个月平均涨幅
FROM funds
GROUP BY fund_type
HAVING count(*) >= 5; -- having筛选条件中只能对分组依据字段进行筛选,或对其他字段进行聚合后筛选

执行顺序

第一步: FROM <left_table>
第二步: ON <join_condition>
第三步: <join_type> JOIN <right_table>
第四步: WHERE <where_condition>
第五步: GROUP BY <group_by_list>
第六步: HAVING <having_condition>
第七步: SELECT
第八步: DISTINCT <select_list>
第九步: ORDER BY <order_by_condition>
第十步: LIMIT <limit_number>

因此在select中定义的别名不能在where或having中使用

表连接

-- 创建商品信息表
CREATE TABLE product_info
(
    product_id       VARCHAR PRIMARY KEY,
    product_category VARCHAR,
    product_name     VARCHAR,
    product_price    FLOAT
);

-- 创建销售记录表
CREATE TABLE sale_records
(
    sold_product_id VARCHAR,
    amount          INT,
    discount        FLOAT
);

-- 插入示例数据
INSERT INTO product_info
VALUES ('ca4ef73a-dd6d-11eb-894e-287fcf8fcac7', '生活用品', '花王蒸汽眼罩12片装', 48.8),
       ('ca4ef73b-dd6d-11eb-922a-287fcf8fcac7', '鞋类', '安踏EDGE跑鞋', 429.0),
       ('ca4ef73c-dd6d-11eb-b7ee-287fcf8fcac7', '鞋类', '匹克态极3.0跑步鞋', 499.0),
       ('ca4ef73d-dd6d-11eb-9fc4-287fcf8fcac7', '办公用品', 'Salli马鞍椅', 2255.0),
       ('ca4ef73e-dd6d-11eb-851b-287fcf8fcac7', '办公用品', 'GAVEE人体工学椅', 3888.0),
       ('ca4ef73f-dd6d-11eb-ba5f-287fcf8fcac7', '办公用品', '赫曼米勒Aeron人体工学椅', 16310.0),
       ('e2d3o9ed-dccb-11eb-we7u-287fcf8fcac7', '数码产品', '华为Mate X2折叠手机', 17799.0);

INSERT INTO sale_records
VALUES ('ca4ef73a-dd6d-11eb-894e-287fcf8fcac7', 2, 0.9),
       ('ca4ef73b-dd6d-11eb-922a-287fcf8fcac7', 6, 0.8),
       ('ca4ef73d-dd6d-11eb-9fc4-287fcf8fcac7', 3, 0.9),
       ('ca4ef73b-dd6d-11eb-922a-287fcf8fcac7', 1, 0.9),
       ('ca4ef73e-dd6d-11eb-851b-287fcf8fcac7', 2, 0.8),
       ('ca4ef73c-dd6d-11eb-b7ee-287fcf8fcac7', 9, 0.7),

内连接

-- 内连接
SELECT DISTINCT product_name FROM sale_records AS a
INNER JOIN product_info AS b
ON a.sold_product_id = b.product_id;

-- 两表中的字段不存在重复,可以省略别名
SELECT DISTINCT product_name FROM sale_records
INNER JOIN product_info
ON sold_product_id = product_id;

左(右)外连接

-- 左外连接
SELECT * FROM product_info
LEFT JOIN sale_records
ON sold_product_id = product_id
WHERE product_name = '华为Mate X2折叠手机';

全外连接

SELECT DISTINCT product_name FROM sale_records
FULL JOIN product_info -- 或 FULL OUTER JOIN (MySQL中没有全外连接)
ON sold_product_id = product_id;

外键约束

-- 创建销售记录表
CREATE TABLE sale_records
(
    sold_product_id VARCHAR REFERENCES product_info(product_id),
    amount          INT,
    discount        FLOAT DEFAULT 1
);

在本例中,即希望sale_records中的sold_prodect_id都能在product_info中找到对应的product_id

INSERT INTO sale_records VALUES ('not_int_product_info', 1, 1); -- 报错,因为product_info表中并不存在product_id为'not_int_product_info'的数据

窗口函数

针对每一条数据单独开一个窗,在窗内执行不同的操作(通常用于既要明细又要聚合的场景)

示例数据:
(SQL学习随笔3)SQL语法——SELECT语句

  • 需求一:获得每个type下播放量前三名对应的记录
SELECT *
FROM (
         SELECT type, author, title, dense_rank() OVER (PARTITION BY type ORDER BY view DESC) AS top3
         FROM bilibili
     ) AS temp
WHERE top3 <= 3;

注意:窗口函数的执行实在WHERE之后的,因此要获取前三名不能在内层直接用WHERE,而是用嵌套查询在外层使用WHERE

  • 需求二:查询每个type中,在coins降序排名下,每个视频与其下一名之间播放量的差值
select *, view - diff as diff_view
from (
    select type, author, title, view, coins, lead(view, 1) over (partition by type order by coins desc) as diff
    from bilibili
    ) as _; -- FROM 中的子查询必须有一个别名

注意:over子句中起的别名不能在同级select中使用,因此还是要用嵌套查询

更多窗口函数:

  • MySQL
    https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html
  • PostgreSQL
    http://www.postgres.cn/docs/12/functions-window.html

UNION:表上下拼接

SELECT * FROM t1
UNION
SELECT * FROM t2
UNION
SELECT * FROM t3

-- 要求:两表具有相同的字段数量,且字段数据类型相互兼容
-- 最终查询到的表头字段与第一张表t1一致
-- UNION 会自动去重,使用UNION ALL不去重

子查询

SELECT *
FROM (
	SELECT * FROM t1
) as _; -- 子查询必须要给予别名
GROUP BY ...

条件判断

  • PostgreSQL示例数据
-- 懂车帝部分车辆评分及价格信息表
CREATE TABLE car_info
(
    brand VARCHAR,
    score FLOAT,
    price VARCHAR
);

INSERT INTO car_info
VALUES ('轩逸', 3.65, '8.48-15.59万'),
       ('雅阁', 3.94, '15.18-24.18万'),
       ('思域', 3.83, '9.49-15.89万'),
       ('朗逸', 3.62, '6.79-15.89万'),
       ('哈弗H6', 3.81, '9.19-15.49万'),
  • MySQL示例数据
-- 懂车帝部分车辆评分及价格信息表
CREATE TABLE car_info
(
    brand TEXT,
    score FLOAT,
    price TEXT
);

INSERT INTO car_info
VALUES ('轩逸', 3.65, '8.48-15.59万'),
       ('雅阁', 3.94, '15.18-24.18万'),
       ('思域', 3.83, '9.49-15.89万'),
       ('朗逸', 3.62, '6.79-15.89万'),
       ('哈弗H6', 3.81, '9.19-15.49万')

PostgreSQL

  • 对值进行匹配

CASE 输入值 WHEN 匹配值1 THEN 结果1 WHEN 匹配值2 THEN 结果2 … ELSE 备选值 END

-- 为奥迪、宝马、五菱开头的品牌单独匹配,其他情况返回other
SELECT CASE left(brand, 2) -- 从左取brand两个字符
           WHEN '奥迪' THEN 'Audi'
           WHEN '宝马' THEN 'BMW'
           WHEN '五菱' THEN 'SGMW'
           ELSE 'other'
           END,
       brand
FROM car_info;
  • 对条件进行匹配

CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 ELSE 备选结果 END

-- 以4为阈值区分高评分与非高评分
SELECT CASE WHEN score > 4 THEN '高评分' ELSE '非高评分' END,
       brand,
       score
FROM car_info;

MySQL

CASE-WHEN-THEN-END结构语法与PostgreSQL一致

IF(条件, 满足条件时返回的值, 不满足条件时返回的值)

-- 以4为阈值区分高评分与非高评分
SELECT if(score > 4, '高评分', '非高评分'),
       brand,
       score
FROM car_info;

IFNULL(a, b),当a为NULL时,返回b;当a不为null时,返回a文章来源地址https://www.toymoban.com/news/detail-427044.html

SELECT IFNULL(null, '是null'), IFNULL('非null', '不返回这个');

到了这里,关于(SQL学习随笔3)SQL语法——SELECT语句的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL基础(三)基本的SELECT语句

    1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖。在这几十年里,无数的技术、产业在这片江湖里沉浮,有的方兴未艾,有的已经几幕兴衰。但在这片浩荡的波动里,有一门技术从未消失,甚至“老当益壮”,那就是 SQL。

    2024年02月03日
    浏览(32)
  • MySQL-03基本的SELECT语句(基础)

    课程中,第二章是MySQL环境搭建,因为我之前安装过MySQL5.7的环境,然后就直接下载8.0版本的zip,直接安装的,就没看视频,所以没有第二章笔记。这里给出MySQL社区版下载地址。 1.1 SQL背景知识 1974年,IBM研究员发布了一篇揭开数据库技术的论文《SEQUEL:一门结构化的英语查询

    2024年02月05日
    浏览(44)
  • MySQL-03.基本的SELECT语句(基础)

    课程中,第二章是MySQL环境搭建,因为我之前安装过MySQL5.7的环境,然后就直接下载8.0版本的zip,直接安装的,就没看视频,所以没有第二章笔记。这里给出MySQL社区版下载地址。 1.1 SQL背景知识 1974年,IBM研究员发布了一篇揭开数据库技术的论文《SEQUEL:一门结构化的英语查询

    2024年02月05日
    浏览(35)
  • BDA初级分析——认识SQL,认识基础语法

    SQL作为实用技能,热度高、应用广泛  在对数据分析人员的调查中SQL长期作为热度排名第-一的编程语言超过Python和R SQL:易学易用,高效强大的语言 SQL: Structured Query Language 结构化查询语言 SQL:易学易用,类似英文语法类的语言结构  SQL:标准语句,写法成熟,应用广泛 SQ

    2024年02月12日
    浏览(29)
  • 基本的SELECT语句——“MySQL数据库”

    各位CSDN的uu们好呀,好久没有更新小雅兰的MySQL数据库专栏啦,接下来一段时间,小雅兰都会更新MySQL数据库的知识,下面,让我们进入今天的主题吧——基本的SELECT语句!!! SQL概述 SQL语言的规则与规范 基本的SELECT语句 显示表结构 过滤数据 1946 年,世界上第一台电脑诞生

    2024年02月09日
    浏览(54)
  • SQL SELECT DISTINCT(选择不同) 语法

    SELECT DISTINCT语法用于仅返回不同的(different)值。 在一张表内,一列通常包含许多重复的值; 有时你只想列出不同的(different)值。 SELECT DISTINCT语句用于仅返回不同的(different)值。 SQL SELECT DISTINCT语法如下所示: 在本教程中,我们将使用著名的 Northwind 样本数据库。 下面

    2024年02月07日
    浏览(47)
  • Mysql数据库(六):基本的SELECT语句

    本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远! 语法: 选择全部列: 一般情况下,除非需要使用表中所有的字段数据,最好不要使用通配符‘ *

    2024年02月08日
    浏览(59)
  • MySQL中,SQL 查询总是先执行SELECT语句吗?

    在使用 MySQL 进行查询时,我们通常会使用 SELECT 语句,但是 SELECT 语句是否总是最先被执行呢?这是一个非常有趣的问题,本文将对此进行探讨。 在 MySQL 中,SQL 查询通常包括以下几个步骤: 语法解析 :MySQL 会对 SQL 查询语句进行语法解析,检查语句是否符合 SQL 语法规范。

    2023年04月09日
    浏览(48)
  • SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解

    SELECT INTO 语句将数据从一个表复制到一个新表中。 新表将按照在旧表中定义的列名和类型创建。您可以使用 AS 子句创建新的列名。 以下 SQL 语句创建 Customers 的备份副本: 以下 SQL 语句使用 IN 子句将表复制到另一个数据库中的新表中: 以下 SQL 语句仅复制一些列到新表中:

    2024年02月05日
    浏览(117)
  • MySQL 参考文档:SQL 语句优化(SELECT 语句优化)之索引条件下推(索引下推)优化

    索引下推优化官方文档说明 (Section 8.2.1.5):https://dev.mysql.com/doc/refman/5.7/en/index-condition-pushdown-optimization.html 1. 什么是索引下推? qquad 索引条件下推 (Index Condition Pushdown,ICP) 是 MySQL 在使用索引从表中检索行时的一种优化方法。在没有 ICP 的情况下,存储引擎遍历索引以定位基

    2024年02月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包