首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Oracle中mysql的Find_in_set的替代方案

Oracle中mysql的Find_in_set的替代方案
EN

Stack Overflow用户
提问于 2015-03-09 12:59:59
回答 3查看 8K关注 0票数 2
代码语言:javascript
运行
复制
select   CASE
          WHEN ComExgRateDetailLog.NotificationMinute = '*'
          THEN
             1
          ELSE
             IF(FIND_IN_SET(
                   CAST(
                      DATE_FORMAT(
                         DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:00'),
                         '%i') AS SIGNED),
                   ComExgRateDetailLog.NotificationMinute) > 0,
                1,
                0)
       END

       From ComExgRateDetailLog

我希望甲骨文也能得到同样的结果。甲骨文中find_in集的替代选项是什么?

在这里,ComExgRateDetailLog.NotificationMinute包含'0,15,30,45‘这样的值,所以查询应该如下

代码语言:javascript
运行
复制
select   CASE
          WHEN ComExgRateDetailLog.NotificationMinute = '*'
          THEN
             1
          ELSE
             IF(FIND_IN_SET(
                   CAST(
                      DATE_FORMAT(
                         DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:00'),
                         '%i') AS SIGNED),
                   '0,15,20,45') > 0,
                1,
                0)
       END

       From ComExgRateDetailLog
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-09 13:53:58

代码语言:javascript
运行
复制
select FIND_IN_SET('15', '0,15,20,45') from dual would return 2

为了实现这一点,在甲骨文中使用INSTR函数,但INSTR与FIND_IN_SET并不完全相同。INSTR将字符串中的逗号、空格、任何内容视为字符。

代码语言:javascript
运行
复制
SELECT INSTR ('0,15,20,45', '15',1,1) FROM dual would return 3

你可以读到关于INSTR的这里

票数 0
EN

Stack Overflow用户

发布于 2018-04-17 20:04:34

这并不是MySQL的FIND_IN_SET的确切替代方案,但在您的示例中(您只需要知道一个值是否包含在逗号分隔的集合中),甲骨文的REGEX_COUNT与regex '^([^,]+,)*your_value(,[^,]+)*$'就合适了。

检查以下SQL查询(对于Oracle).

带数字的例子

在集合中搜索数字1[1,2,3,4,5,6,11,12,13]

代码语言:javascript
运行
复制
SELECT
    CASE WHEN REGEXP_COUNT('1,2,3,4,5,6,11,12,13', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END AS cnt
FROM DUAL;

正确返回1

搜索集合中的号码1:111,222,333。在这种情况下,INSTR将无法报告阴性。

代码语言:javascript
运行
复制
SELECT
    CASE WHEN REGEXP_COUNT('111,222,333', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END AS cnt
FROM DUAL;

正确返回0

带有字符串的示例

在一组名称中搜索'John'

代码语言:javascript
运行
复制
SELECT
    CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*John(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

正确返回1

如果您想要区分大小写的搜索,请将REGEXP_COUNT的最后一个参数从'i'替换为'c' (按照文档)。

但是,如果您搜索字母'a',它将正确返回零(INSTR将再次失败)。

代码语言:javascript
运行
复制
SELECT
    CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*a(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

正确返回0

我知道这个问题早在很久以前就已经被回答了,但它在搜索结果中排名很好,可能会帮助其他人寻找比甲骨文的INSTR函数更简单但更正确的解决方案。

布尔表达式

也可以使用布尔表达式,如ORAND

使用OR的一个示例如下:

代码语言:javascript
运行
复制
SELECT
    CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*(helen|peter)(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

返回正确的1,因为它找到了"peter“(搜索"helen”或"peter")。

对于AND,方法有点不同(修改案例表达式而不是regex):

代码语言:javascript
运行
复制
SELECT
    CASE WHEN
            REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*john(,[^,]+)*$', 1, 'i') > 0 AND
            REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*peter(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

上面的查询搜索"john“ "peter”。通过复制AND语法中的REGEXP_COUNT表达式,可以轻松地实现CASE操作,但代价很小。

票数 4
EN

Stack Overflow用户

发布于 2016-03-09 00:20:07

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION find_in_set(
  i_value  IN  VARCHAR2,
  i_list   IN  VARCHAR2,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN INT DETERMINISTIC
AS
  p_result       INT       := 0;
  p_start        NUMBER(5) := 1;
  p_end          NUMBER(5);
  c_len CONSTANT NUMBER(5) := LENGTH( i_list );
  c_ld  CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
  IF c_len > 0 THEN
    p_end := INSTR( i_list, i_delim, p_start );
    WHILE p_end > 0 LOOP
      p_result := p_result + 1;
      IF ( SUBSTR( i_list, p_start, p_end - p_start ) = i_value )
      THEN
        RETURN p_result;
      END IF;
      p_start := p_end + c_ld;
      p_end := INSTR( i_list, i_delim, p_start );
    END LOOP;
    IF p_start <= c_len + 1
       AND SUBSTR( i_list, p_start, c_len - p_start + 1 ) = i_value
    THEN
      RETURN p_result + 1;
    END IF;
  END IF;
  RETURN 0;
END;
/
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28942608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档