V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
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 · 102 天前 · 1712 次点击
    这是一个创建于 102 天前的主题,其中的信息可能已经有所发展或是发生改变。
    名字内的任意部分,不能包含有指定列表里的所有元素。注意是任意部分,而不是整个。

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

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

    求助 V 友!
    第 1 条附言  ·  102 天前
    补充描述

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

    我目前的逻辑是看 L20 在不在定义的名称列表里,然后自定义一个排除 L20 的其他列表。SQL 写的时候要表达的有点类似于,name in namelist1 AND name not in namelist2 ,(但这样只支持了完整的名字,而没有支持 name like 这样的部分匹配),所以实际不清楚怎么快速表达
    第 2 条附言  ·  101 天前
    @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 条回复    2022-03-18 21:01:41 +08:00
    boshok
        1
    boshok  
       102 天前
    语死早
    binux
        2
    binux  
       102 天前 via Android   ❤️ 1
    用 regex
    feitxue
        3
    feitxue  
       102 天前   ❤️ 1
    自定义敏感词检测是吧.
    没在 sql 实现.
    在代码里实现的.
    java 的话,我之前用的这个 https://github.com/houbb/sensitive-word
    dayeye2006199
        4
    dayeye2006199  
       102 天前   ❤️ 1
    对 name 分词或者生成 ngram 之后,和 namelist 取交集。如果交集为空就是不包含。
    但是 op 你这个描述太含糊了,name 是中文还是英文,是自然语言还是一些机器码之类的,都会影响到你怎么实现的。
    youthfire
        5
    youthfire  
    OP
       102 天前 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  
       102 天前
    问题的描述太碎片了,可能是出于保密的需求

    1.输入一个字符串 str
    2.表 table1 中有一个字段 name
    3.要求匹配 name 最接近字符串 str 的?
    youthfire
        7
    youthfire  
    OP
       102 天前 via iPhone
    @THESDZ #6 谢谢理解,对,比如输入 ASD L20 ,会识别出对应是 L20 ,从数据库找出 L20 。而忽略 L2007 ,虽然 L20 和 L2007 都在常用名列表中。
    dongtingyue
        8
    dongtingyue  
       102 天前
    输入 GGL2007 GGL 2007 是两种不通情况的需求。
    后者可以名字入库的时候先分词,搜索内容也分词后进行搜索。
    前者你的水平实现不了要的功能。
    zmal
        9
    zmal  
       102 天前   ❤️ 1
    好像只能在内存里处理。你的需求有点像 elasticsearch 的相关度概念,可以自己用代码简单撸一个。不要苛求都可以在 sql 里解决。
    onhao
        10
    onhao  
       102 天前   ❤️ 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  
       102 天前   ❤️ 1
    如果匹配的逻辑比较简单,即 name in (keys) 和一个长度最接近
    可以考虑 char_length 和 abs 两个函数的运用
    pengtdyd
        12
    pengtdyd  
       102 天前
    垃圾产品设计
    hooopo
        13
    hooopo  
       102 天前
    你先把产品需求讲明白吧 求求你了
    youthfire
        14
    youthfire  
    OP
       101 天前
    @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 友无法理解表示歉意,实际上我只是想对关键用法得到思路,并没有获取完整代码的需求,因此也没有花过多精力就不方便透露的内容作更多措辞和需求形容,无论如何,依然很高兴从这里得到了启发。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3983 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:33 · PVG 17:33 · LAX 02:33 · JFK 05:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.