【SQL】排序与运算、筛选函数

1、字段间的算术运算 

销量 = 备货量 - 库存量,那么,让备货量对应的字段 total 减去库存量对应的 surplus,结果是实际销量。SQL 会根据我们给出的算式,按行执行字段与字段之间的数学运算,最终的计算结果也被保存到了一个新的字段中,新字段的名称就是原算式 total - surplus。

SELECT  event_name,
        total,
        surplus,
        total - surplus
FROM    stocks;

2、round()函数--保留指定位数的小数

  • round(待处理的算式/数据, 保留小数的位数)
  • eg:round(surplus/total, 2)
SELECT  event_name,
        total,
        surplus,
        round(surplus/total, 2)
FROM    stocks;

3、AS关键字

用 AS 关键字给字段取别名,这里的字段可以是数据表中的单独一列,也可以是算术运算后得到的新字段。

--比如下面的语句,可以给 total - surplus 取别名为 sales,意为销量:
SELECT event_name,
price,
total - surplus AS sales
FROM stocks;

--用中文作别名
SELECT  event_name         AS 演出名称,
        price              AS 价格,
        total - surplus    AS 销量
FROM    stocks;

取别名时的注意事项:在三种情况下,要在别名两侧加反引号

  1. 别名与SQL中的关键字相同。例: `where `
  2. 别名以数字开头。例: `2020年销售额 `
  3. 别名中包含特殊字符。例: `互联网+ `

4、ORDER BY 子句--按指定字段对查询结果进行排序。

默认情况下,ORDER BY 子句的结果为升序(从低到高)排列

--按多个字段排序
--对 stocks 表按 演出类型 - 价格 排序的语句,写成:
SELECT *
FROM stocks
ORDER BY event_type, price;

这里 event_type 作为外层排序依据,price 作为内层排序依据,SQL 会首先按 event_type,将同类型的数据组织到一起,再在每个类型内部按 price 字段排序。

SQL 对于中文会按照拼音排序,对于英文则是按照字母顺序排序的。

-- 按字段别名排序
-- 按英文别名排序
SELECT   event_name,
         price,
         total - surplus    AS sales
FROM     stocks
ORDER BY sales;

-- 按中文别名排序
SELECT   event_name         AS 演出名称,
         price              AS 价格,
         total - surplus    AS 销量
FROM     stocks
ORDER BY 销量;

指定排序方向

  • 从低到高 ORDER BY price ASC (升序排序关键字可省略)
  • 从高到低 ORDER BY price DESC (降序排序关键字)

5、LIMIT 关键字--限制查询结果的数量

LIMIT 关键字用于限制查询结果的数量,接收的两个参数分别为获取的起始位置(也即起始行号 - 1),和一共获取的行数,从起始位置开始,一直向后数指定个数字,也就得到了待获取的行号。

LIMIT 3, 4 的含义就是从 3 开始往后数 4 个数字,得到 4,5,6,7,以此作为待获取的行号。

以 LIMIT 0, 5 为例,起始位置是 0,返回结果的行数是 5,那么,从 0 开始往后数 5 个数,就得到了待获取的行号:1, 2, 3, 4, 5,最终返回了第 1~5 行数据。

LIMIT 5 相当于 LIMIT 0, 5

-- 找到 话剧 类型的演出中 售卖比最高的 5 场
SELECT   event_name                         AS 演出名称,
         price                              AS 价格,
         event_type                         AS 演出类型,
         (total - surplus) * price          AS 销售额,
         round((total - surplus)/total, 2)  AS 售卖比
FROM     stocks
WHERE    演出类型 = '话剧'
ORDER BY 售卖比 DESC
LIMIT 5;

6、datetime()函数

datetime(需要处理的日期字段, 原日期字段的格式)

eg:datetime(pay_time,' unixepoch')

把 pay_time 列从 Unix 时间戳格式日期,转换成标准格式的日期
 

7、substring()函数

substring (需要处理的字段, 开始提取位置, 提取字符个数)
eg:substring (tracking_num, 1, 2);

--tracking_num 中前两个字母是我们需要提取出的快递公司编号信息,所以写成 SQL 语句就是这样:
SELECT  substring(tracking_num, 1, 2)	AS 快递公司编码
FROM    orders;
--让计算机对于 tracking_num 字段中的每一行,都从第 1 个字符开始,提取出长度为 2 的字符串,也就是提取出前两个字母

--判断提取出来的信息是否为 HX
SELECT  tracking_num                         AS 快递单号,
        substring(tracking_num, 1, 2) = 'HX' AS 是否为自营
FROM    orders;
--是否为自营 一列中的数据不是 0 就是 1
--SQLite 默认使用 0 来表示 假、不成立 的概念,用 1 来表示 真、成立 的概念

8、iif()函数

iif( 需要判断的条件, 满足条件时在结果对应行填入的值, 不满足条件时在结果对应行填入的值)

eg:iif( substring (tracking_num, 1, 2) = ‘HX', '是', '否')

SELECT  tracking_num    AS 快递单号,
        iif(
                substring(tracking_num, 1, 2) = 'HX', -- 需要判断的条件
                '是', -- 满足条件时填入的值
                '否'  -- 不满足条件时填入的值
            )           AS 是否为自营
FROM    orders;

跟统计相关的函数:

  • count():统计行数;
  1. 参数为 *:统计选择范围内所有行(包括存在空值的行)的个数;
  2. 参数为 字段名:统计该字段中,所有 非空值 行的个数;
  3. 参数为 DISTINCT 字段名:统计该字段中,唯一 非空值 行的个数。
  • min():统计最小值;
  • max():统计最大值;
  • avg():统计平均值;
  • sum():统计所有数值之和。

-- 在 SQLite 中,整数与整数作除法时,会舍去小数点后的数值
-- 所以两个计算字段,都需要在前面乘以 1.0,写成形如 1.0 * 计算公式 的形式,避免损失精度
SELECT  round(1.0*(sum(price*amount))/count(DISTINCT user_id), 2)
            AS 平均消费金额,
        round(1.0*(sum(amount))/count(DISTINCT user_id), 2)
            AS 平均购买门票张数
FROM    orders;

9、GROUP BY 子句--将原数据进行 分组

GROUP BY 分组依据;

eg:GROUP BY user_id;

SQL 会先执行 GROUP BY 子句,再执行 SELECT 子句。

10、HAVING 子句--筛选分组结果

HAVING 筛选依据;

-- 筛选出所有新用户啦
-- 同时满足 R 高(R > 32)、F 不高于2(F <= 2)、M 低(M < 1180)这三个条件的用户才是新用户
-- 并按照 M 降序、F 降序、R 升序 的顺序,对结果进行排序
SELECT   user_id                                       AS 用户ID,
         user_name                                     AS 用户昵称,
         (1641052799 - max(pay_time)) / (24 * 60 * 60) AS R,
         count(user_id)                                AS F,
         sum(price * amount)                           AS M
FROM     orders
GROUP BY user_id
HAVING   R > 32
   AND   F <= 2
   AND   M < 1180
ORDER BY M DESC, F DESC, R;

执行顺序是:

  1. FROM 子句:从 orders 数据表中读取数据,确定后续查询的数据来源;
  2. GROUP BY 子句:根据 user_id 列的值进行分组;
  3. HAVING 子句:从分组结果中筛选出符合 R > 32 AND F <= 2 AND M < 1180 条件的分组;
  4. SELECT 子句:从最终结果中选择出若干列、计算字段进行展示。

子查询:用一对圆括号()包裹,作为一个元素参与到外层查询中的查询。

-- 从此处开始写外层查询
SELECT      item_id, item_name
FROM        items
WHERE       item_id IN
    -- 用圆括号将子查询内容包裹起来
    (
         SELECT      item_id
         FROM        user_behavior
         WHERE       type = 'buy'    -- 筛选出类型为 buy 的数据
         GROUP BY    item_id         -- 按 item_id 进行分组
         ORDER BY    count(*)  DESC  -- 按每组数据的数量进行降序排序
         LIMIT       1               -- 选取出第一条数据,也就是购买人数最多的商品
     );
-- 外层查询编写完毕,别忘了加上分号哦

 把子查询作为外层查询的计算字段:

-- 根据 items 数据表中记录的 brand_id 信息,检索出 brands 数据表中对应的 brand_name
-- 并作为一个计算字段,展示在最终的结果表里
SELECT  (
            SELECT brand_name
            FROM   brands
            WHERE  brands.brand_id = items.brand_id
        )           AS 品牌名,
        item_name   AS 商品名
FROM    items;
SELECT count(iif(type = 'pv', 1, NULL))             AS A,
       count(iif(type IN ('fav', 'cart'), 1, NULL)) AS I,
       count(iif(type = 'buy', 1, NULL))            AS P,
       (
           SELECT   count(*)
           FROM (
                    SELECT   count(*) AS 购物次数
                    FROM     user_behavior
                    WHERE    type = 'buy'
                    GROUP BY user_id
                    HAVING   购物次数 > 1
                )
       )                                            AS L
FROM   user_behavior;

 AS关键字给表取别名

SELECT  datetime(ub.time, 'unixepoch')  AS 购买时间,
        ub.user_name                    AS 用户名,
        i.item_name                     AS 商品名,
        b.brand_name                    AS 品牌名
FROM    user_behavior                   AS ub,
        items                           AS i,
        brands                          AS b
WHERE   ub.item_id = i.item_id
  AND   i.brand_id = b.brand_id
  AND   ub.type = 'buy';

JOIN --把两张数据表 联结 起来

SELECT  datetime(time, 'unixepoch') 购买时间,
        user_name                   用户名,
        item_name                   商品名,
        brand_name                  品牌名
FROM    user_behavior   ub
        JOIN    items   i   ON ub.item_id = i.item_id
        JOIN    brands  b   ON i.brand_id = b.brand_id
WHERE   type = 'buy';

LEFT JOIN

把 LEFT JOIN 关键字之前的数据表作为主表,把后面的作为次表。在创建联结时,先把主表中的所有数据誊抄一遍,再把次表中符合联结条件的数据拼接在后面。可以完全保留主表中的数据。

SELECT  *
FROM    items     i
        LEFT JOIN item_data id  ON i.item_id = id.item_id
             JOIN brands    b   ON i.brand_id = b.brand_id;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值