时间:2021-07-01 10:21:17 帮助过:12人阅读
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 语法可以在 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 语法,我们可以把 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
兄弟连学python(1)——MySQL
标签:not from -- 发放 需求 app 学习交流 func cti