一张表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')))
这样,我感觉这样不行呀,求大神们给一个牛逼一点的答案吧,谢谢啦
1
eason1874 2022-07-25 21:19:04 +08:00
才 30 万数据,eq OR IN 行啊,别混在一起写, 需求里每个“如果”都分开写,然后 OR 连在一起
|
2
xy90321 2022-07-25 21:34:41 +08:00 via iPhone
非要在 SQL 做是有什么难处吗 🤔
|
3
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 ``` |
4
sunmoon1983 OP @xy90321 您给个其它的方案也行,谢谢啦
|
5
weidaizi 2022-07-26 14:02:53 +08:00
稍微复杂一点的逻辑判断都不应该直接写到 sql 里,直接流式读出来,然后在代码里写逻辑过滤比较好
|
6
xy90321 2022-07-26 21:44:33 +08:00 via iPhone
@sunmoon1983
能动表结构吗?能动的话就加一个零概率事件与否的标志位,每天 batch 去洗一遍。 抽表根据标志位去抽就可以了,需要的话就加个 index ,不过才三十万,都还好吧? 有实时性需求的话考虑加个 procedure… 不能动表的话按照同样思路做个 view ? 否则的话按照你的“笨办法”就可以了,能实现是第一要务。 不在 SQL 做的话就要抽出来在程序里做了,用年龄性别做 SQL 条件先过一遍,剩下的 code 在程序里判断… |
7
sunmoon1983 OP @xy90321 因为我有分页显示的需求,我是想新建一张同样结构的表,然后再加一个标志位,然后通过程序把符合条件的数据都筛出来,再把这些数据都写到新表中,不知道这样可行否?谢谢您的回答
|
8
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 |