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
我在oracle中想要相同的结果。在oracle中设置find_in的替代选项是什么?
此处ComExgRateDetailLog.NotificationMinute
包含类似'0,15,30,45'的值,因此查询应该像
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
答案 0 :(得分:3)
不是MySQL FIND_IN_SET
的精确替代品,但在您的示例中(您只需要知道如果一个值包含在以逗号分隔的集合中)Oracle的REGEX_COUNT
{ 3}}正则表达式'^([^,]+,)*your_value(,[^,]+)*$'
适合。
检查以下SQL查询(对于Oracle)...
在集合中搜索号码1
:[1,2,3,4,5,6,11,12,13]
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将不会报告否定。
SELECT
CASE WHEN REGEXP_COUNT('111,222,333', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
THEN 1 ELSE 0
END AS cnt
FROM DUAL;
正确退回 0
在一组名称中搜索'John'
:
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
如果您需要区分大小写的搜索,请根据documentation将
'i'
的最后一个REGEXP_COUNT参数替换为'c'
。
但是如果你搜索字母'a'
,它将正确返回零(INSTR会再次失败)。
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
我知道这个问题很久以前就得到了解答,但它在搜索结果中排名很好,可能会帮助其他人寻找一个比Oracle INSTR
函数更简单但更正确的解决方案。< / p>
也可以使用布尔表达式,如OR
或AND
。
使用OR
的示例如下:
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
,因为它找到了&#34; peter&#34; (搜索&#34; helen&#34; 或&#34; peter&#34; )。
对于AND
,方法略有不同(修改 CASE表达式而不是正则表达式):
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;
上述查询会搜索&#34; john&#34; AND &#34; peter&#34; 。通过复制AND
语法中的REGEXP_COUNT
表达式,可以轻松实现CASE
操作,但是性能损失很小。
答案 1 :(得分:2)
select FIND_IN_SET('15', '0,15,20,45') from dual would return 2
为了在oracle中实现这一点,请使用INSTR函数,但INSTR与FIND_IN_SET并不完全相同。 INSTR将逗号,空格,字符串中的任何内容视为字符。
SELECT INSTR ('0,15,20,45', '15',1,1) FROM dual would return 3
您可以阅读INSTR here。
答案 2 :(得分:2)
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;
/