最近的BI项目, 就是会涉及大量的 sql, 后台处理也全是 sql 来拼接成一张物理宽表, 然后前台也是用 sql 来做各种图形骚操作. 尤其是后台处理部分, 大量的sql, 有点尴尬的事情是, sql 好像没有编程语言的 "数据结构", 只是一些数据类型. 不像编程语言, 比如我最熟悉的 Python, 它有列表, 有二维数组, 或者在分析中最常用的 DataFrame, 可以用一个变量来进行指向. SQL 就尴尬了, 我在写的时候, 经常会有各种, 嵌套或子查询的代码, 大多是重复的, 不断 复制粘贴, 会显得sql 很长, 且性能和可读性都比较差. 因此, 需要一个, "临时变量" 来存储中间过程, 就跟咱编程一样, 定义变量来指向某个 "数据结构" 是一样的.

虽然我当前用的是 IQ Sybase 数据库, 它也是关系型, 列式的, 查询贼快, 写入倒不大行. 关系型 sql 都是基于标准 sql 差不多的呀, 只是一个语法, 函数之类的不同而已. 这里呢, 以 mysql 为例, 切换会上网搜索就行.

我最需要的一个操作, 通常就是, 将一段 sql 查询的结果进行分情况处理, 大致如下:

  • 存为 物理表: create table 物理表名 as ( 查询集sql ) ;
  • insert 的方式: insert into 表名 (查询集sql); 前提是表存在哦;
  • 存为 临时表: create temporary table as (查询集sql) ;
  • 存为 视图表: crate view 视图名 as (查询集sql) ;

...

大致就这些情况, 然后来分别演练一把, 也是总结一下, 方面自己做笔记储备, 以后复制粘贴能更快一些呢.

数据准备

查询集 sql , 我也是随便写了一段, 用的是比较熟悉的 超市数据集, 即 Tableau 自带的那个, 维度和度量都比较合适, 比较适合用来做 Demo 分析的呢.

如何将 Excel / csv 数据转为 sql : https://www.cnblogs.com/chenjieyouge/p/12865933.html

Pandas 将Excel 写入 Mysql: https://www.cnblogs.com/chenjieyouge/p/11811784.html

终端 : load data local infile 'D:/tb_01.csv' into cj_tb fields terminated by ',' lines terminated by '\n';

如何将数据导入 数据库这种基础必备操作, 就不想谈了, 一搜一大把, 网上, 开心就好~

-- 不同地区的销售额
select
region,
sum(sales) as sum_sales
from cj.super_market
group by region
+--------+------------+
| region | sum_sales |
+--------+------------+
| 东北 | 2681567.48 |
| 中南 | 4137415.09 |
| 华东 | 4684506.51 |
| 华北 | 2447301.07 |
| 西北 | 815039.57 |
| 西南 | 1303124.51 |
+--------+------------+
6 rows in set (0.01 sec)

然后呢, 需要基于此, 查询集, 再增加个字段, N_S 就分为 "南方" 和北方. 当然正常操作是在底表上做, 这里只是,为了演示, 为了 "嵌套" 而嵌套哈.

select
region,
sum_sales,
case
when region like '%北%' then '北方'
when region in ('西南', '中南') then '南方'
else '未知'
end as N_S
from (
select
region,
sum(sales) as sum_sales
from cj.super_market
group by region
) as a
+--------+------------+--------+
| region | sum_sales | N_S |
+--------+------------+--------+
| 东北 | 2681567.48 | 北方 |
| 中南 | 4137415.09 | 南方 |
| 华东 | 4684506.51 | 未知 |
| 华北 | 2447301.07 | 北方 |
| 西北 | 815039.57 | 北方 |
| 西南 | 1303124.51 | 南方 |
+--------+------------+--------+
6 rows in set (0.01 sec)

类似的, 子查询, 我是几乎每天都要这样写很多.... 而且远远比这个更加复杂, 嵌套也更多, 在性能和可读性上都非常难受, 自己都维护不了, 因此, 尽量要少用多层子查询, 而将一段逻辑就存为一个临时表多好.

存为临时表 temporary

临时表, 在会话结束后, 就会自动销毁, 类似于程序中的变量嘛, 用完就回收了, 尤其是在优化查询逻辑, 且不需要长期占用物理内存的时候, 特别有用哦.

对于查询集的写法: **create temporary table 表名 as (查询集sql) ; **

-- 可将第一个 group by查询集, 存为一个临时表
drop table if exists tmp_market_01; create temporary table tmp_market_01 as (
select
region,
sum(sales) as sum_sales
from cj.super_market
group by region );

这样就将 临时表 tmp_market_01 建好了, show tables; 是找不到该临时表的, 当然原理是它存在其他地方了哈, 当会后结束后, 就会自动销毁了呢. 最大用处在于可以优化子查询. 于是 呢, 上面的子查询就可以这样优化了.

drop table if exists tmp_market_01;  

create temporary table tmp_market_01 as (
select
region,
sum(sales) as sum_sales
from cj.super_market
group by region ); select
region,
sum_sales,
case
when region like '%北%' then '北方'
when region in ('西南', '中南') then '南方'
else '未知'
end as N_S -- 查询集, 作为临时, 极大提高了性能和可读性, 难道不香嘛
from tmp_market_01;
+--------+------------+--------+
| region | sum_sales | N_S |
+--------+------------+--------+
| 东北 | 2681567.48 | 北方 |
| 中南 | 4137415.09 | 南方 |
| 华东 | 4684506.51 | 未知 |
| 华北 | 2447301.07 | 北方 |
| 西北 | 815039.57 | 北方 |
| 西南 | 1303124.51 | 南方 |
+--------+------------+--------+
6 rows in set (0.01 sec)

临时表用来, 优化子查询, 是真的香哇.. 尤其是我上篇那个, 嵌套了 6层的 大sql, 简直是临时表优化, 势在必行呢. 这就跟 "变量" 一样, 每一个复杂的步骤, 就建一个临时表 (当然也不要太频繁, IO 也会影响性能), 这样, 对我作为开发来说, 是 可读性和可维护性 极大提高, 反例就来看看我之前的嵌套 5-6层的 大SQL, 绝对让你们 "大开眼界".

存为视图 view

相对于存为临时表, 将查询结果集. 我基于之前的经验, 更多是存为一个视图. 当然视图本质上就是一个一段sql , 不是真正的表, 只是一段 "封装的sql 逻辑" , 并不会有多少查询上的优化, 好处是随着其物理表动态变化的, 我也是用的比较多些.

对于查询集的写法: **create view table 视图名 as (查询集sql) ; **

-- 存为视图, 同样能在可读性上做优化的
drop view if exists v_market_01; create view v_market_01 as (
select
region,
sum(sales) as sum_sales
from cj.super_market
group by region ); select
region,
sum_sales,
case
when region like '%北%' then '北方'
when region in ('西南', '中南') then '南方'
else '未知'
end as N_S
-- 查询集作为视图, 只是隐藏逻辑而已, 其实性能上并未优化
from v_market_01;

此时呢, 再进行 show tables; 就可以看到该视图了, 跟临时表不同. 如果是要经常用到的话, 当然建议用视图, 如果是优化性能和逻辑, 如生成宽表, 纯用 sql 的话, 临时表也许更加合适, 具体情景, 具体分析吧. 查询优先用视图, 写罗写打断逻辑, 优化用临时表.

存为物理表

也分为两种方式, create 和 insert into.

  • create 的方式, 如果表已经存在, 则会报错嘛 => create table 表名 as (查询集 sql);
  • insert into 的方式, 如表存在, 则会继续 insert, 表不存在, 则报错 => insert into 表名 (s查询集 sql);

IQ Sybase 中, create 方式的写法是 select * into 表名 from (sql 查询集)

具体怎么用, 也是看场景的, 比如我上篇那个, 需要先建一个目标表, 然后分步骤, 不断用 查询集往里面 insert 数据; 另一种就是在数据处理的时候, 需要这么一张物理表, 就直接用 select 的方式了呀.

create 方式

对于查询集的写法: **create table 表名 as (查询集sql) ; **

drop table if exists tb_market_01;  

create table tb_market_01 as (
select
region,
sum(sales) as sum_sales
from cj.super_market
group by region );

如果表重复就会报错, 当然, 通常有配合 if exists ... 将结果存为为物理表, 尤其是我做BI的 时候, 会经常用的, 基于一大堆或者多段的 sql 生成了一个 "宽表" 将其存为一个真实数据集, 在用 BI来连上前台, 继续进行各种 sql 操作.

insert into 方式

对于查询集的写法: **insert into table 表名 (查询集sql) ; **

-- insert into 表 (查询集),  这里没有 as 哦; 表不存在则报错
insert into tb_market_01 (
select
region,
sum(sales) as sum_sales
from cj.super_market
group by region );

当然还有一种骚操作, 就是先存一个空表字段, 然后再不断地 insert , 我有用过这样的.

drop table if exists tb_market_01;  

create table tb_market_01 as (
select
region,
sum(sales) as sum_sales
from cj.super_market
-- 这就跟创建表, 写成每个字段其实是一样的呢
where 1 = 2
group by region );

小结

  • create temporary table 表名 as (查询集sql) ;
  • create view table 视图名 as (查询集sql) ;
  • create table 表名 as (查询集sql) ;
  • insert into table 表名 (查询集sql) ;

将查询集SQL-存为物理 OR 临时表的更多相关文章

  1. 簡單SQL存儲過程實例

    簡單SQL存儲過程實例 摘自:http://blog.csdn.net/libra6956/article/details/5589173 实例1:只返回单一记录集的存储过程. 银行存款表(bankM ...

  2. 看懂SqlServer查询计划 SQL语句优化分析

    转自 http://www.cnblogs.com/fish-li/archive/2011/06/06/2073626.html 阅读目录 开始 SQL Server 查找记录的方法 SQL Ser ...

  3. django-数据库的查询集

    1.curd(增删改查) 对于数据库,作为一名开发人员并不会感到陌生,那么数据库中的查询集是怎么一回事呢? 2.数据库的查询集 查询集这个概念存在django框架中,存在于ORM(object rel ...

  4. django 过滤器-查询集-比较运算符-FQ对象-mysql的命令窗口

    """ 返回查询集的方法称为过滤器 all() 返回查询集中所有数据 filter() 返回符合条件的数据 一.filter(键=值) 二.filter(键=值,键=值) ...

  5. 提高SQL查询效率(SQL优化)

    要提高SQL查询效率where语句条件的先后次序应如何写 http://blog.csdn.net/sforiz/article/details/5345359   我们要做到不但会写SQL,还要做到 ...

  6. Hibernate查询之SQL查询

    转自: Hibernate还支持使用SQL查询,使用SQL查询可以利用某些数据库的特性,或者用于将原有的JDBC应用迁移到Hibernate应用上.使用命名的SQL查询还可以将SQL语句放在配置文件中 ...

  7. 查询集API -- Django从入门到精通系列教程

    该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...

  8. Django 查询集简述

    通过模型中的管理器构造一个查询集(QuerySet),来从数据库中获取对象.查询集表示从数据库中取出来的对象的集合.它可以含有零个.一个或者多个过滤器.过滤器基于所给的参数限制查询的结果. 从SQL ...

  9. django查询集API

    本节将详细介绍查询集的API,它建立在下面的模型基础上,与上一节的模型相同: from django.db import models class Blog(models.Model): name = ...

  10. django 查询集 API

    filter 表示=, 返回一个新的QuerySet,包含与给定的查询参数匹配的对象.exclude 表示!=. 返回一个新的QuerySet,它包含不满足给定的查找参数的对象. annotate 使 ...

随机推荐

  1. 解锁DeepSeek深度应用,天翼云GPU云主机强势破局!

    在人工智能重塑世界的当下,一场影响深远的科技变革正在悄然上演,DeepSeek系列模型在诸多领域掀起热潮.企业级AI模型的训练与部署,不仅是技术的角力场,更是决定企业兴衰的生死线.每一次算法的迭代革新 ...

  2. [ABC213G] Connectivity 2 题解

    好好好. 我们设当前处理 \(i\) 的答案,那么最后的图就可以分成两个部分:\(1\) 所在的联通块和其他,根据乘法原理,答案就是它们二者方案的乘积. 设 \(f_s\) 表示集合 \(s\) 中所 ...

  3. 安川MH225机械手CPU单元维修解决方案

    在进行安川机器人cpu单元维修之前,我们需要做好充分的准备工作.首先,了解机器人的使用环境和历史情况,了解机器人出现故障的具体表现,例如:是否有异常震动.过热等现象.其次,准备必要的维修工具和备件,确 ...

  4. 【Spring Boot】我的第一个Spring Boot练习

    背景 Spring 在 Java 生态的企业级开发项目中极其常用,通常我们为项目引入一项新技术时,不得不考虑如何将新技术与 Spring 整合在一起. 我们知道,预研一项新技术,我们基于 MVP(最简 ...

  5. Feedalyze - 让你听得见、听得清用户的反馈

    满足用户需求,解决用户问题,获得适当报酬是商业成功最为重要的因素.然而扪心自问,当您推出新产品后,您真的在听.听得见.听得清用户的反馈么? 当今信息传播迅猛,渠道繁多,优秀产品随口碑效应供不应求,劣质 ...

  6. 【数值计算方法】线性方程组迭代算法的Python实现

    线性方程组迭代算法的Python实现 jacobi,GS,SOR迭代法 def JacobiIter(A:np.ndarray, b:np.ndarray, tol:float=1e-5, maxIt ...

  7. 理解Python中的元类(metaclass)

    类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...

  8. 2D小游戏--猜对应卡牌(unity)

    博客地址:https://www.cnblogs.com/zylyehuo/ 项目名称 guess_card_game 参考源码链接: https://www.manning.com/books/un ...

  9. 当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系

    <当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系> 引言:一场OOM引发的血案 某个月黑风高的夜晚,监控系统突然发出刺耳的警报--我们的数据发现流水线集体扑街.事后复盘 ...

  10. MySQL 事务隔离级别:社交恐惧症的四个阶段

    MySQL 事务隔离级别:社交恐惧症的四个阶段 在数据库的世界里,数据们也有社交问题!事务隔离级别就是控制它们互相看到对方的程度... 什么是事务隔离? 想象一下,数据库是一个繁忙的餐厅,每个事务都是 ...