兄弟连学python(1)——MySQL

MySQL官网:http://www.mysql.com

MySQL是WEB应用方面最好的RDBMS应用软件之一

RDBMS:Relational Database Management System关系数据库管理系统

使用 UNION | UNION ALL 语法

UNION 用于合并多个查询的结果集,我目前遇到的主要有如下两个场景用起来比较有效:

1. 同表的复杂查询,很难通过一个 SELECT 语句搞定
2. 多表查询,但返回的数据一致,常见一些聚合数据统计需求

UNION 也可以加 limit、order by 子句,用于对 UNION 后的结果集进行排序和过滤。

通过 UNION 的这些特性,我们可以把原本需要编写代码才能处理的一些工作交给数据库,同时还减少 SQL 数,提高性能。

比如说,下面这个例子:

select ‘product‘ as type, count(*) as count from `products`
union
select ‘comment‘ as type, count(*) as count from `comments`
order by count;

我们通过 UNION 语法同时查询了 products 表 和 comments 表的总记录数,并且按照 count 排序。

结合 UPDATE | DELETE 与 JOIN

一直以来,我们得益于联合查询(SELECT + JOIN)给我们带来的便利,但无形之中确形成了思维定势(至少对于我而言是这样的),殊不知 UPDATE DELETE 也能与 JOIN 联合使用,从而简化 SQL 编写。

在使用 UPDATE | DELETE + JOIN 之前,我们可能做法要么是先查询出待删除记录的 ID 然后再根据 ID 进行删除,要么是使用 IN 子查询。前者需要写两个 SQL 语句,在程序中处理逻辑,后者有时并不能正常工作。

就后者而言,应该有人遇到过这样的错误:

ERROR 1093 (HY000): You can‘t specify target table ‘xxx‘ for update in FROM clause

这样的错误产生的原因是:MySQL 不支持同一个 SQL 语句尝试对同一个表进行查询和修改两个操作。

比如,删除没有评论的文章这条语句

delete from articles 
where id in (
select a.id from articles as a left join comments as c on a.id=c.article_id 
where c.is is NULL
)

articles 表既被查询,也被更新,将出现上面的错误。

但是,如果 DELETE 结合 JOIN,则可以直接写出这样的 SQL 语句,简洁许多:

delete s from articles as a 
left join comments as c on a.id=c.article_id 
where c.is is NULL

当然,UPDATE 也是同理:

update articles as a 
left join comments as c on a.id=c.article_id 
set a.deleted=1 
where c.is is NULL

CASE 语法

CASE 语法可以在 SQL 内做简单的分支判断,根据不同的条件返回不同的值。比如考虑这样的需求:

一个商品有多个订单,订单有已付款和未付款两个状态,现在给定一个商品列表,返回每个商品已付款和未付款订单的数量。

这个时候我们可以通过 CASE 语句和 GROUP BY 通过一条 SQL 实现:

select 
product_id, 
count(
case is_paid
when 1 then 1
else null
end
) as total_paid,
count(
case is_paid
when 0 then 1
else null
end
) as total_not_paid
from orders
where product_id in (1, 2, 3, 4)
group by product_id;

配合 ORM 库,这样的写法可以帮助我们实现 eager loading,避免 n + 1 查询。

因为这个场景比较简单,我们也可以使用 MySQL 提供的流程控制函数(Control Flow Functions) 使得该 SQL 更简洁:

select 
product_id, 
count(if(is_paid = 1, 1, null)) as total_paid,
count(if(is_paid = 0, 1, null)) as total_not_paid
from orders
where product_id in (1, 2, 3, 4)
group by product_id;

使用 INSERT INTO ... SELECT 语法

通过 INSERT INTO ... SELECT 语法,我们可以把 SELECT 的结果集直接写入另一张表中,而不需要程序处理。通过这个语法,外加一些变通,我们可以很方便的实现更多的需求场景。

比如说,我们要给所有购买了某一商品的用户发放一张元价值10元的优惠券,我们可以这样写:

insert into tickets (user_id, price, expires_in) 
select 
user_id, 10 as price, ‘2017-09-09‘ as expires_in 
from orders 
where product_id=123 and is_paid=1;

又比如说,在选课的场景中,我们要给一批人分配一批课,假设要给1班的人分配体育课和美术课,我们可以通过该语法加 CROSS JOIN 实现:

insert into class_members (class_id, user_id, status) 
select 
c.id as class_id, 
u.id as user_id, 
1 as status
from classes as c cross join users as u
where c.name in (‘体育课‘, ‘美术课‘) and u.class_name=‘1班‘;

----------------Python学习交流、资源共享群:563626388 QQ

时间: 2024-10-08 11:35:54

兄弟连学python(1)——MySQL的相关文章

兄弟连学python 课堂笔记 ---- Redis类型

Redis通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型. String(子串类型) set 命令:设置一个键和值,键存在则只覆盖,返回ok > set 键  值    例如: >set name zhangsan get 命令:获取一个键的值,返回值 > get 键        例如:>get name setnx命令:设置一个不存在的键和值(

兄弟连学python 课堂笔记 ---- Redis基本操作

基本操作 Redis 是 Key-Value 内存数据库,操作是通过各种指令进行的,比如 `SET` 指令可以设置键值对,而 `GET` 指令则获取某一个键的值.不同的数据结构,Redis 有不同的指令,这样指令一共有几十个,下面主要介绍一些常用的指令. Redis 对 Key 也就是键有各种各样的指令,主要有下面的指令(下面的指令中小写字符串都是参数,可以自定义):>keys *  //返回键(key) >keys list*   //返回名以list开头的所有键(key)>exist

2017年12月12日 兄弟连学Python 课堂笔记 ---- mysql触发器

MySQL的触发器 格式:1.触发器的定义: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt 说明: # trigger_name:触发器名称 # trigger_time:触发时间,可取值:BEFORE或AFTER # trigger_event:触发事件,可取值:INSERT.UPDATE或DELETE. # tb1_name:指定在哪个表上 # trig

兄弟连学Python 课堂笔记 ---- mysql数据操作

添加数据 格式: insert into 表名[(字段列表)] values(值列表...);--标准添加(指定所有字段,给定所有的值)  insert into stu(id,name,age,sex,classid) values(1,'zhangsan',20,'m','lamp138');Query OK, 1 row affected (0.13 sec) --指定部分字段添加值 insert into stu(name,classid) value('lisi','lamp138')

兄弟连学python(26) --- if not

python if not 判断是否为None的情况 if not x if x is None if not x is None if x is not None`是最好的写法,清晰,不会出现错误,以后坚持使用这种写法. 使用if not x这种写法的前提是:必须清楚x等于None, False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()时对你的判断没有影响才行 ==============转载至http://blog.csdn.net/sasoritattoo/

兄弟连学Python(06)------- 条件语句和循环语句

Python的条件语句和循环语句的基础知识: 1.条件语句:包括单分支.双分支和多分支语句,if-elif-else 2.循环语句:while的使用及简单网络刷博器爬虫 3.循环语句:for的使用及遍历列表.元组.文件和字符串 在讲诉条件语句.循环语句和其他语句之前,先来补充语句块知识.(前面讲函数时已经用到过) 语句块并非一种语句,它是在条件为真(条件语句)时执行或执行多次(循环语句)的一组语句.在代码前放置空格或tab字符来缩进语句即可创建语句块.很多语言特殊单词或字符(如begin或{)来

兄弟连学python (01) ----表单的设计

简单的表单编辑:<!DOCTYPE HTML> <html lang='en'> <head> <meta chaset='utf-8'/> <title>from练习</title> </head> <body> <from> <table width='500px' height='700px' border='2' align='center'> <tr> <td

兄弟连学python (02) ----简易抽奖器

import tkinter import random import tkinter.messagebox class choujiang: def __init__(self): self.root=tkinter.Tk() self.root.minsize(400,400) self.root.resizable(width=False,height=False) self.root.title("简单抽奖器") self.result1 = tkinter.StringVar

在兄弟连学Python Python的数据类型

在Python中可以自定义的数据内容有无数种,但是系统默认的标准类型有六种: 一.Number 类型 分为四种类: Int 整型 Float 浮点型 Bool 布尔类型 String 字符串类型 字符串类型就是用引号括起来的文字类型: 每一种引号中都可以包含其他的俩中引号方式.也可以使用转义字符的方式 注: 转义字符: Complex 复数类型 二.List  列表类型 列表是一组有顺序的数据组合,且可修改.列表的标识符号为[ ] 例子:    list1 = [1,3,4,5,8] 三.Tup