› 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
youthfire
V2EX  ›  MySQL

求助一个 SQL 表达

  •  
  •   youthfire · Mar 18, 2022 · 3641 views
    This topic created in 1668 days ago, the information mentioned may be changed or developed.
    名字内的任意部分,不能包含有指定列表里的所有元素。注意是任意部分,而不是整个。

    假设整个名字的话是
    select * from nametable where name not in namelist

    那名字内的任意部分该怎么表达呢?列表里的元素很多,我不能够每个都写一句 name not like %element%

    求助 V 友!
    Supplement 1  ·  Mar 18, 2022
    补充描述

    我想对产品的型号检测,产品型号名字许多都非常接近或类似。比如型号有 L20 ,L2035 ,L2007 。对输入框内容检测,我已经按照一定包含关系排序检测,比如先看有没有 L2035 ,没有的话再看 L20 ,来确定输入的型号。但如果要查看 L20 就麻烦,会带出 L2035 和 L2007 。实际上原始输入还不是正好型号内容,还有其他字符,比如 GGL2007 这样。

    我目前的逻辑是看 L20 在不在定义的名称列表里,然后自定义一个排除 L20 的其他列表。SQL 写的时候要表达的有点类似于,name in namelist1 AND name not in namelist2 ,(但这样只支持了完整的名字,而没有支持 name like 这样的部分匹配),所以实际不清楚怎么快速表达
    Supplement 2  ·  Mar 18, 2022
    @binux 确实用了正则顺利解决,感谢! 还顺便学习了 sqlite 开启 REGEXP 的方法
    @thesdz @onhao 长度问题给了我启发,谢谢!
    关键代码:

    def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

    conn = sqlite3.connect(r'/Users/' + username + '/veradb.db')
    conn.create_function("REGEXP", 2, regexp)
    df = pd.DataFrame(pd.read_sql('select * from f61 where client = ? AND type REGEXP ? AND type NOT REGEXP ?', conn, params=[str(client), str(type), str(type) + "."]))

    由于主要是担心搜 L20 被包含进 L2007,所以加一个.即可
    感觉所有参与给我提供思路的 V 友,也对没有清晰表述造成部分 V 友无法理解表示歉意,实际上我只是想对关键用法得到思路,并没有获取完整代码的需求,因此也没有花过多精力就不方便透露的内容作更多措辞和需求形容,无论如何,依然很高兴从这里得到了启发。
    14 replies  •  2022-03-18 21:01:41 +08:00
    boshok
        1
    boshok  
       Mar 18, 2022
    语死早
    binux
        2
    binux  
       Mar 18, 2022 via Android   ❤️ 1
    用 regex
    feitxue
        3
    feitxue  
       Mar 18, 2022   ❤️ 1
    自定义敏感词检测是吧.
    没在 sql 实现.
    在代码里实现的.
    java 的话,我之前用的这个 https://github.com/houbb/sensitive-word
    dayeye2006199
        4
    dayeye2006199  
       Mar 18, 2022   ❤️ 1
    对 name 分词或者生成 ngram 之后,和 namelist 取交集。如果交集为空就是不包含。
    但是 op 你这个描述太含糊了,name 是中文还是英文,是自然语言还是一些机器码之类的,都会影响到你怎么实现的。
    youthfire
        5
    youthfire  
    OP
       Mar 18, 2022 via iPhone
    谢谢,还真有点敏感词的意思。

    我想对产品的型号检测,产品型号名字许多都非常接近或类似。比如型号有 L20 ,L2035 ,L2007 。对输入框内容检测,我已经按照一定包含关系排序检测,比如先看有没有 L2035 ,没有的话再看 L20 ,来确定输入的型号。但如果要查看 L20 就麻烦,会带出 L2035 和 L2007 。实际上原始输入还不是正好型号内容,还有其他字符,比如 GGL2007 这样。

    我目前的逻辑是看 L20 在不在定义的名称列表里,然后自定义一个排除 L20 的其他列表。SQL 写的时候要表达的有点类似于,name in namelist1 AND name not in namelist2 ,(但这样只支持了完整的名字,而没有支持 name like 这样的部分匹配),所以实际不清楚怎么快速表达。 @feitxue @dayeye2006199
    THESDZ
        6
    THESDZ  
       Mar 18, 2022
    问题的描述太碎片了,可能是出于保密的需求

    1.输入一个字符串 str
    2.表 table1 中有一个字段 name
    3.要求匹配 name 最接近字符串 str 的?
    youthfire
        7
    youthfire  
    OP
       Mar 18, 2022 via iPhone
    @THESDZ #6 谢谢理解,对,比如输入 ASD L20 ,会识别出对应是 L20 ,从数据库找出 L20 。而忽略 L2007 ,虽然 L20 和 L2007 都在常用名列表中。
    dongtingyue
        8
    dongtingyue  
       Mar 18, 2022
    输入 GGL2007 GGL 2007 是两种不通情况的需求。
    后者可以名字入库的时候先分词,搜索内容也分词后进行搜索。
    前者你的水平实现不了要的功能。
    zmal
        9
    zmal  
       Mar 18, 2022   ❤️ 1
    好像只能在内存里处理。你的需求有点像 elasticsearch 的相关度概念,可以自己用代码简单撸一个。不要苛求都可以在 sql 里解决。
    onhao
        10
    onhao  
       Mar 18, 2022   ❤️ 1
    select *,strlen(title)len from (select * from nametable where name like '%key%') tmp order by len

    @youthfire 以上提供一个思路,不保证运行,

    https://wuhao.pw/category/mysql/
    THESDZ
        11
    THESDZ  
       Mar 18, 2022   ❤️ 1
    如果匹配的逻辑比较简单,即 name in (keys) 和一个长度最接近
    可以考虑 char_length 和 abs 两个函数的运用
    pengtdyd
        12
    pengtdyd  
       Mar 18, 2022
    垃圾产品设计
    hooopo
        13
    hooopo  
       Mar 18, 2022
    你先把产品需求讲明白吧 求求你了
    youthfire
        14
    youthfire  
    OP
       Mar 18, 2022
    @binux 确实用了正则顺利解决,感谢! 还顺便学习了 sqlite 开启 REGEXP 的方法
    @thesdz @onhao 长度问题给了我启发,谢谢!
    关键代码:

    def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

    conn = sqlite3.connect(r'/Users/' + username + '/veradb.db')
    conn.create_function("REGEXP", 2, regexp)
    df = pd.DataFrame(pd.read_sql('select * from f61 where client = ? AND type REGEXP ? AND type NOT REGEXP ?', conn, params=[str(client), str(type), str(type) + "."]))

    由于主要是担心搜 L20 被包含进 L2007,所以加一个.即可
    感觉所有参与给我提供思路的 V 友,也对没有清晰表述造成部分 V 友无法理解表示歉意,实际上我只是想对关键用法得到思路,并没有获取完整代码的需求,因此也没有花过多精力就不方便透露的内容作更多措辞和需求形容,无论如何,依然很高兴从这里得到了启发。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1977 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 00:01 · PVG 08:01 · LAX 17:01 · JFK 20:01
    ♥ Do have faith in what you're doing.