如何计算Oracle varchar值中字符出现次数?

时间:2011-11-17 15:11:30

标签: sql oracle count oracle10g

如何计算varchar2字符串中字符-的出现次数?

示例:

select XXX('123-345-566', '-') from dual;
----------------------------------------
2

9 个答案:

答案 0 :(得分:58)

你走了:

select length('123-345-566') - length(replace('123-345-566','-',null)) 
from dual;

从技术上讲,如果要检查的字符串仅包含要计数的字符,则上述查询将返回NULL;以下查询将在所有情况下给出正确的答案:

select coalesce(length('123-345-566') - length(replace('123-345-566','-',null)), length('123-345-566'), 0) 
from dual;

coalesce中的最后一个0捕获了你在空字符串中计数的情况(即NULL,因为ORACLE中的长度(NULL)= NULL)。

答案 1 :(得分:56)

REGEXP_COUNT应该这样做:

select REGEXP_COUNT('123-345-566', '-') from dual;

答案 2 :(得分:11)

这是一个想法:尝试用空字符串替换不是短划线字符的所有内容。然后计算剩下多少破折号。

select length(regexp_replace('123-345-566', '[^-]', '')) from dual

答案 3 :(得分:4)

我justed遇到了非常类似的问题...但是RegExp_Count无法解决它。 字符串'16,124,3,3,1,0'包含',3,'多少次?我们看到2次,但RegExp_Count只返回1.同样的事情是''bbaaaacc',当查看'aa'时 - 应该是3次,而RegExp_Count只返回2。

select REGEXP_COUNT('336,14,3,3,11,0,' , ',3,') from dual;
select REGEXP_COUNT('bbaaaacc' , 'aa') from dual;

我在网上研究解决方案时失去了一些时间。无法'找到......所以我写了自己的函数,返回TRUE的出现次数。希望它会有用。

CREATE OR REPLACE FUNCTION EXPRESSION_COUNT( pEXPRESSION VARCHAR2, pPHRASE VARCHAR2 ) RETURN NUMBER AS
  vRET NUMBER := 0;
  vPHRASE_LENGTH NUMBER := 0;
  vCOUNTER NUMBER := 0;
  vEXPRESSION VARCHAR2(4000);
  vTEMP VARCHAR2(4000);
BEGIN
  vEXPRESSION := pEXPRESSION;
  vPHRASE_LENGTH := LENGTH( pPHRASE );
  LOOP
    vCOUNTER := vCOUNTER + 1;
    vTEMP := SUBSTR( vEXPRESSION, 1, vPHRASE_LENGTH);
    IF (vTEMP = pPHRASE) THEN        
        vRET := vRET + 1;
    END IF;
    vEXPRESSION := SUBSTR( vEXPRESSION, 2, LENGTH( vEXPRESSION ) - 1);
  EXIT WHEN ( LENGTH( vEXPRESSION ) = 0 ) OR (vEXPRESSION IS NULL);
  END LOOP;
  RETURN vRET;
END;

答案 4 :(得分:3)

我想到了

 SELECT LENGTH('123-345-566') - LENGTH(REPLACE('123-345-566', '-', '')) FROM DUAL;

答案 5 :(得分:1)

这是一个适用于字符和子字符串的解决方案:

select (length('a') - nvl(length(replace('a','b')),0)) / length('b')
  from dual

其中a是搜索b

出现的字符串

度过愉快的一天!

答案 6 :(得分:0)

SELECT {FN LENGTH('123-345-566')} - {FN LENGTH({FN REPLACE('123-345-566', '#', '')})} FROM DUAL

答案 7 :(得分:0)

select count(*)
from (
      select substr('K_u_n_a_l',level,1) str
      from dual
      connect by level <=length('K_u_n_a_l')
     )
where str  ='_';

答案 8 :(得分:0)

您可以尝试

import numpy as np
import gpflow 

def generate_data(N=100):
    X = np.random.rand(N)[:, None] * 10 - 5  # Inputs, shape N x 1
    F = 2.5 * np.sin(6 * X) + np.cos(3 * X)  # Mean function values
    groups = np.arange( 0, N, 1 ).reshape(-1,1)  
    NoiseVar = np.array([i/100.0 for i in range(N)])[groups]  
    Y = F + np.random.randn(N, 1) * np.sqrt(NoiseVar)  # Noisy data
    return X, Y, groups, NoiseVar

# Get data
X, Y, groups, NoiseVar = generate_data()
Y_data = np.hstack([Y, groups])
# Generate one likelihood per data-point
likelihood = gpflow.likelihoods.SwitchedLikelihood( [gpflow.likelihoods.Gaussian(variance=NoiseVar[i]) for i in range(Y.shape[0])])

# model construction (notice that num_latent is 1)
kern  = gpflow.kernels.Matern52(input_dim=1, lengthscales=0.5)
model = gpflow.models.VGP(X, Y_data, kern=kern, likelihood=likelihood, num_latent=1)
# Specify the likelihood as non-trainable
model.likelihood.set_trainable(False)

# build the natural gradients optimiser
natgrad_optimizer = gpflow.training.NatGradOptimizer(gamma=1.)
natgrad_tensor    = natgrad_optimizer.make_optimize_tensor(model, var_list=[(model.q_mu, model.q_sqrt)])
session = model.enquire_session()
session.run(natgrad_tensor)
# update the cache of the variational parameters in the current session
model.anchor(session)

# Stop Adam from optimising the variational parameters
model.q_mu.trainable   = False
model.q_sqrt.trainable = False
# Create Adam tensor
adam_tensor = gpflow.train.AdamOptimizer(learning_rate=0.1).make_optimize_tensor(model)
for i in range(200): 
    session.run(natgrad_tensor)
    session.run(adam_tensor)
# update the cache of the parameters in the current session
model.anchor(session)
print(model)

“正确”算出“ bbaaaacc”中有多少“ aa”

select count( distinct pos) from
(select instr('123-456-789', '-', level) as pos from dual
  connect by level <=length('123-456-789'))
where nvl(pos, 0) !=0