【问题标题】:SQL - Combining multiple like queriesSQL - 组合多个类似查询
【发布时间】:2011-01-15 18:37:21
【问题描述】:

嘿,我关于 SO 的第一个问题!任何人...

在 SQL 方面还是个新手,所以我想我可能在这里遗漏了一些东西。我的问题是我目前有一个完整的电话号码表。我想要一个查询,在其中搜索与我拥有的列表相似的电话号码。例如,我想查找以“555123”、“555321”和“555987”开头的电话号码。我通常知道如果你有一个数字列表,你可以做一个查询,比如

SELECT * 
  FROM phonenumbers 
 WHERE number in ('5551234567', '5559876543', .... );

有没有办法用like来做到这一点?比如

SELECT * 
  FROM phonenumbers 
 WHERE number in like ('555123%', '555321%', '555987%'); //I know this doesn't actually work

而不是必须单独执行此操作

SELECT * 
  FROM phonenumbers 
 WHERE number like '555123%' 
    or number like '555321%' 
    or number like '555987%'; //Which does work but takes a long time

或者我只是想念一个更容易做到这一点的方法吗?我正在使用 postgres,我不知道它是否有任何命令可以帮助解决这个问题。谢谢!

【问题讨论】:

  • 欢迎来到 SO!我已经重新标记了您的问题,以澄清它与 postgres 相关
  • 什么版本的 Postgres?听起来像是正则表达式的工作:postgresql.org/docs/8.3/static/functions-matching.html
  • Which does work but takes a long time - 除非您更改查询的性质,否则同一事物的不同语法表示将花费很长时间。该列是否已编入索引?
  • 实际上该列已被索引。我以前没有注意到这一点。哦,我正在使用 postgres 8.0。我正在搜索大量数字。
  • 您的查询需要多长时间?您的表中有多少条记录?

标签: sql postgresql


【解决方案1】:

您可以使用SIMILAR TO 并用| 分隔标签管道'555123%|555321%|555987%'

例如:

SELECT * 
FROM phonenumbers 
WHERE number SIMILAR TO '555123%|555321%|555987%'

【讨论】:

    【解决方案2】:

    晚会,但为了后代...您也可以使用ANY(array expression)

    SELECT * 
    FROM phonenumbers 
    WHERE number LIKE ANY(ARRAY['555123%', '555321%', '555987%'])
    

    【讨论】:

    【解决方案3】:

    假设你所有的数字都不包含字母,并且你的数字总是“前缀”(例如:LIKE '123%'):

    SELECT  number
    FROM    (
            VALUES
            ('555123'),
            ('555321'),
            ('555000')
            ) prefixes (prefix)
    JOIN    phonenumbers
    ON      number >= prefix
            AND number < prefix || 'a'
    

    这将使用phonenumbers 上的索引(如果有),因此可能会更快。

    【讨论】:

    • 你有博客或打算写一本关于这些的书吗?我会成为买家之一。
    • @Pentium10: explainextended.com 这本书正在制作中,但这是个秘密,请不要告诉任何人。
    【解决方案4】:

    我不这么认为,但您可以将 phonenumbers 加入到包含您要匹配的值的表 criteria 上,即

    JOIN criteria ON phonenumbers.number LIKE criteria.phonenumbers
    

    ...在少数情况下可能不值得,但

    【讨论】:

    • 其实我还有很多东西要搜索,但我想我应该用几个数字来保持简单。
    • 或创建临时表。可能不会从其他选项中获得任何加速,而是一个选项哇。
    【解决方案5】:

    您还可以依赖 POSIX 正则表达式,请参阅official documentation 的第 9.7.3 节。

    例如:

    SELECT * FROM foobar WHERE name ~ '12345|34567';
    

    请务必注意,您的 name 字段属于字符串类型。

    【讨论】:

    • 不知道为什么,但这个解决方案是唯一对我有用的解决方案。
    【解决方案6】:

    也许如果您的前缀长度相同,那么您可以使用where RIGHT(number) in ('123456', '234456', 'etc', 'etc')

    【讨论】:

      猜你喜欢
      • 2016-10-27
      • 2019-01-07
      • 1970-01-01
      • 2018-07-15
      • 2017-09-02
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多