mysql中case的用法

哦,还有你提到的CASE语句,当我第一次接触MySQL时,我被震撼了。
不过,使用多次后,我发现它还是蛮实用的。
我给大家讲一下我遇到的坑。

当时,我在一家小公司担任数据分析师。
他们的数据库有一个名为 order 的表,其中存储了大量订单信息。
有一个栏叫Status,是订单状态,如“Pending”、“Shipped”、“Delivered”等。
我的老板让我创建一个报告并将状态更改为中文。
“pending”表示“待处理”,“shipped”表示“已发货”,所有其他表示“未知”。

一开始我尝试使用 IF 语句,但结果非常难看,有几行。
后来我想,CASE语句不是神器吗?这是我写的:
SQL 选择您的订单 ID, 状态, 案例 当状态 =“待处理”时,则“待处理” 当状态=“已发货”时,则“已发货” 其他“未知” END AS status_chinese 来自订单;
嘿嘿,不是更容易吗?当时,我多次尝试覆盖所有统计数据。
当我提交结果的时候,老板夸奖我说:“报告终于清楚了。
”当时我的心里是多么美好。

然后我遇到了更复杂的情况。
例如,我们曾经有一个名为 Sales 的表,其中包含地区(region)和金额(sales)。
我想按地区统计销售额,我的要求是:

北美必须按原始金额计算。

欧洲地区金额x 1 .1
亚洲的金额将是1 .2 倍。

其他地区的金额是0.9 倍
这个要看情况,所以正常的算术公式是肯定不行的。
我又用了CASE语句。

sql 选择您所在的地区并 SUM(CASE WHEN 地区 = '北美' THEN 金额 ELSE 金额 CASE 当地区=“欧洲”时,则 1 .1 THEN 1 .2 如果区域 = '亚洲' 其他 0.9 结束) ASAdjusted_amount 来自销售 按地区分组;
可以看到里面嵌套了CASE语句。
当我写这篇文章时,我坐在工作站上调试了好几次,尤其是嵌套部分让我几乎头晕。
当最终结果出来时,我松了口气,因为结果符合预期。

CASE语句当然是一个很好的功能,特别是在处理需要区分的数据时。
但条件必须是同一类型,不能混合。
如果不混合的话会报错。
如果区域都是字符串并且金额都是数字,如上例所示,则没有问题。

你还有其他用途吗?哦对了,还有一种情况。
例如,我曾经有一个名为“员工”的表,其中包含一个名为“年龄”的列。
我想按年龄组统计人数:

2 0 岁以下
2 0岁至3 0岁
3 0多岁到4 0多岁
4 0岁以上
也可以使用CASE语句。

sql 选择 案例 2 0岁如果该人未满 2 0 岁,则“2 0 岁以下” 如果年龄在2 0岁到3 0岁之间,则“2 0岁到3 0岁” 如果年龄在3 0岁到4 0岁之间,则“3 0岁到4 0岁” 其他“4 0+” 以age_group结尾, COUNT() AS 计数 来自员工 按年龄组分组;
这份报告给我留下了深刻的印象,因为它是针对人力资源部门的,我对每个年龄段的人员分布特别感兴趣。

一般来说,CASE 语句一开始可能看起来有点复杂,但是随着使用它们,它们会变得更容易。
这在处理需要条件判断的场景时特别有用。
但最大的陷阱是,当条件类型不匹配时,调试变得特别乏味。
通常,小的类型问题会导致整个查询出错,因此您必须逐一进行故障排除。

我以前从来没有接触过这个?我不敢乱说。
不管怎样,这些年来我经常使用 CASE 语句,它们基本上可以在每个项目中使用。

如何在mysql中使用IF条件函数实现逻辑判断

上周,我的朋友正在学习MySQL的IF条件函数,他真的很擅长使用它。
该任务简单实用,语法为IF(状态、真值、假值)as IF(分数>=6 0、‘通过’、‘不及格’),以便根据学生的成绩进行评判。
在 SELECT 查询中也尝试过,对结果非常满意。

2 02 3 年,我在项目中使用了IF函数来更新库存状态,即IF(stock>0, '有货', '缺货')。
这样,随着库存的变化,产品状态也会相应变化。

朋友也提到嵌套的IF可以处理多分支逻辑,但是要注意缩进和括号,不要乱来。
他制定了三个等级,并将成绩从 9 0 分到不及格进行分类。

在UPDATE语句中,IF函数可以大显身手。
比如根据库存更新产品状态,非常方便。

在INSERT语句中,IF函数可以给变量赋值。
例如,它根据商品的价格放置标签。
如果价格高,则标记为“高价”,如果价格普通,则标记为“普通”。

IF函数与CASE语句的比较 IF函数适用于单层或小型分支,而CASE语句适用于复杂的多分支逻辑。
当分支数量超过3 个时,最好使用case语句。

还熟悉避免过度嵌套、处理 NULL 值和性能问题等预防措施,包括在大型表中使用时对条件字段建立索引。

使用逻辑IF函数确实可以提高MySQL查询的灵活性。
我的朋友说,在学习了这一点后,他对数据库工作感到更加得心应手。
不过,他说有时他还是会突然想到别的事情。
例如,有时需要其他函数来处理更复杂的逻辑。
算了,我就不展开了,你可以理解的。

如何使用 MySQL 按条件筛选 DISTINCT 字段?

说实话,当我使用MySQL进行重复数据删除和过滤时,最头疼的是我要照顾各种情况。
你列出的这些方法都很实用。
我补充一下我发现的一些陷阱以及实际操作的细节。

比如方法一中的UNIONALL,我在处理电商平台的域名去重需求时差点就陷入了陷阱。
当时有业务需要将“海外”域名去重结果和“国内”域名去重结果合并起来,但客户又要求不要重复输入同一个域名。
一开始我很困惑。
直接使用UNIONALL会导致同一个域名被放置两次。
最后我改用UNION来去除重复项。
所以请记住,UNIONALL 保留所有重复项,而 UNION 实际上删除重复项。
这是一个很大的区别。

CASE语句方法2 ,我有一个与成员标签去重相关的具体场景。
例如,您想过滤所有具有“海外VIP”标签的会员,但有些会员具有“海外VIP”和“国内黄金”标签。
如果继续使用CASEWHENloc='overseas' THENdomain END,你会发现这些“海外VIP”会员会被过滤掉,因为CASE会先匹配“国内黄金”。
然后,我重写为 CASEWHENloc='overseas' AND (other label field IS NULL OR other label field NOT IN ('domestic gold')) THENdomain END。
当时我不明白为什么业务要这样设计,但又必须这样写。

方法3 GROUPBY+HAVING,最近做报表的时候经常用到。
例如,您想统计所有有“海外”记录的域名,或者一个域名下只有一条记录的域名。
一个细节是SUM(loc='海外')这种写法其实效率不是很高。
我实际上已经测试过,写回 SUM(CASEWHENloc='overseas' THEN1 ELSE0 END) 会更快。
此外,HAVING 子句中的条件必须涵盖所有情况。
例如,如果编写 SUM(loc='overseas')>0,则将统计位置为“海外”和“未知”的记录。
这可能是业务需求,也可能不是预期的。
我在做项目的时候,就因为这个误读了数据。

方法4 窗口函数,刚接触的时候感觉脑子要炸了。
例如,您的要求是保留每个域中最新的“海外”订单,同时排除所有“国内”订单。
我编写的第一个版本是WITHranked_data AS (SELECTdomain, ROW_NUMBER() OVER(PARTITION BY domain ORDER BY timestamp DESC) AS rn FROM table_name WHERE loc='overseas') SELECT DISTINCT domain FROM rating_data WHERE rn=1 原来所有“国内”订单的域名也都进行了去重,然后我才意识到需要添加WHERE rn=1 AND loc='overseas'。
而对于MySQL 8 .0的窗口函数,我建议你首先检查EXPLAIN中的主列是否为domain和timestamp。
如果不是,则考虑更改索引。

归根结底,这个方法很大程度上依赖于实践。
我有一张表,里面有多年积累的用户行为数据。
当我使用 windows 函数删除重复项时,它被卡住了。
然后我发现将时间戳字段转换为索引是有效的。
所以记住,当数据量很大的时候,索引比什么都好,但是索引设计本身就是一门科学。
如果数据量在1 00万以下,通常UNION或CASE就足够了;如果是的话超过千万,最好在窗口函数前加一个WHERE条件来过滤数据。