› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
sunmoon1983
V2EX  ›  MySQL

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

  •  
  •   sunmoon1983 · Jul 25, 2022 · 3553 views
    This topic created in 1538 days ago, the information mentioned may be changed or developed.

    一张表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')))

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

    8 replies  •  2022-07-27 17:31:52 +08:00
    eason1874
        1
    eason1874  
       Jul 25, 2022
    才 30 万数据,eq OR IN 行啊,别混在一起写, 需求里每个“如果”都分开写,然后 OR 连在一起
    xy90321
        2
    xy90321  
       Jul 25, 2022 via iPhone
    非要在 SQL 做是有什么难处吗 🤔
    zhemejinnameyuan
        3
    zhemejinnameyuan  
       Jul 25, 2022
    可以用 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
        4
    sunmoon1983  
    OP
       Jul 26, 2022
    @xy90321 您给个其它的方案也行,谢谢啦
    weidaizi
        5
    weidaizi  
       Jul 26, 2022
    稍微复杂一点的逻辑判断都不应该直接写到 sql 里,直接流式读出来,然后在代码里写逻辑过滤比较好
    xy90321
        6
    xy90321  
       Jul 26, 2022 via iPhone
    @sunmoon1983
    能动表结构吗?能动的话就加一个零概率事件与否的标志位,每天 batch 去洗一遍。
    抽表根据标志位去抽就可以了,需要的话就加个 index ,不过才三十万,都还好吧?
    有实时性需求的话考虑加个 procedure…

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

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

    不在 SQL 做的话就要抽出来在程序里做了,用年龄性别做 SQL 条件先过一遍,剩下的 code 在程序里判断…
    sunmoon1983
        7
    sunmoon1983  
    OP
       Jul 27, 2022
    @xy90321 因为我有分页显示的需求,我是想新建一张同样结构的表,然后再加一个标志位,然后通过程序把符合条件的数据都筛出来,再把这些数据都写到新表中,不知道这样可行否?谢谢您的回答
    asmile1993
        8
    asmile1993  
       Jul 27, 2022
    -- 创建张维表,结构如下, 划分好每个 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
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2641 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 00:43 · PVG 08:43 · LAX 17:43 · JFK 20:43
    ♥ Do have faith in what you're doing.