求大神解答,这种 sql 应该怎么写?

2022-07-25 21:06:53 +08:00
 sunmoon1983

一张表table1吧里面有 30W 数据,字段为id bigint(20),full_name varchar(66) age tinyint(3),code varchar(6) gender tinyint(1) 要展示符合下面这些条件的记录:

如果年龄大于 1 岁,code 在( P00-P96 )这个范围内,则认为存在零概率事件-年龄与原因存在逻辑错误。 如果年龄在 15-55 岁以外,并为女性,code 在( O00-O99 )这个范围内,则认为存在零概率事件-年龄与原因存在逻辑错误 如果年龄在 15 岁以下,code 在( C11 )、C15 )、( C16 )、C18-C21 )、( C22 )、( C33-C34 )、( C67 )访问内,则认为存在零概率事件-年龄与原因存在逻辑错误 如果年龄在 5 岁以下,code 在( I05-I09 )范围内,则认为存在零概率事件-年龄与原因存在逻辑错误

这种 sql 我应该怎么写?想了半天,只想出了一个最笨的方法 SELECT * FROM table1 WHERE (age>1 AND age<5 AND code IN('P00','P01','I05','I09')) OR (age>=5 AND age<15 AND code IN('C11','C15','C67') OR (age>=15 and age<55 AND gender=0 AN code IN('O00','O99')))

这样,我感觉这样不行呀,求大神们给一个牛逼一点的答案吧,谢谢啦

2400 次点击
所在节点    MySQL
8 条回复
eason1874
2022-07-25 21:19:04 +08:00
才 30 万数据,eq OR IN 行啊,别混在一起写, 需求里每个“如果”都分开写,然后 OR 连在一起
xy90321
2022-07-25 21:34:41 +08:00
非要在 SQL 做是有什么难处吗 🤔
zhemejinnameyuan
2022-07-25 21:51:02 +08:00
可以用 case when 试试,条件自己根据情况修改下
```
SELECT
count(case when (age>1 and code in ('P00','P01','P96')) then 1 else null end) as '条件 1',
count(case when (age<5 and code in ('I05','I06','I09')) then 1 else null end) as '条件 2'
FROM
table_name
```
sunmoon1983
2022-07-26 08:45:39 +08:00
@xy90321 您给个其它的方案也行,谢谢啦
weidaizi
2022-07-26 14:02:53 +08:00
稍微复杂一点的逻辑判断都不应该直接写到 sql 里,直接流式读出来,然后在代码里写逻辑过滤比较好
xy90321
2022-07-26 21:44:33 +08:00
@sunmoon1983
能动表结构吗?能动的话就加一个零概率事件与否的标志位,每天 batch 去洗一遍。
抽表根据标志位去抽就可以了,需要的话就加个 index ,不过才三十万,都还好吧?
有实时性需求的话考虑加个 procedure…

不能动表的话按照同样思路做个 view ?

否则的话按照你的“笨办法”就可以了,能实现是第一要务。

不在 SQL 做的话就要抽出来在程序里做了,用年龄性别做 SQL 条件先过一遍,剩下的 code 在程序里判断…
sunmoon1983
2022-07-27 07:52:07 +08:00
@xy90321 因为我有分页显示的需求,我是想新建一张同样结构的表,然后再加一个标志位,然后通过程序把符合条件的数据都筛出来,再把这些数据都写到新表中,不知道这样可行否?谢谢您的回答
asmile1993
2022-07-27 17:31:52 +08:00
-- 创建张维表,结构如下, 划分好每个 code 的年龄范围
-- 也可以不创建,用子查询创建个临时的结果集
create table code_age(
code varchar(20),
age_start varchar(20),
age_stop varchar(20)
)

-- 再根据 code 和原表 table1 关联,并根据 age 来筛选
select a.*
from table1 a inner join
code_age b
where a.code = b.code
and a.age > b.age_start
and a.age < b.age_stop

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/868651

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX