2013-10-03 4 views
2

가정하자, 나는 다음과 같은 결과 집합을 가지고 :MySQL의 시퀀스 나누기/홀을 효율적으로 계산하는 방법은 무엇입니까?

SELECT 
    * 
FROM 
    (
     SELECT 1 as `no`, NULL as `sequence` 
     UNION ALL 
     SELECT 2, '' 
     UNION ALL 
     SELECT 3, '1' 
     UNION ALL 
     SELECT 4, '1,2,3,4,5' 
     UNION ALL 
     SELECT 5, '2,4,5' 
     UNION ALL 
     SELECT 6, '1, 5' 
     UNION ALL 
     SELECT 7, '1,3,5' 
    ) as `sub`; 

내 작업 순서 나누기를 계산했다/아래에 나열된 각 sequence위한 구멍. 내가 저장 기능 다음 서면으로 작성했습니다 :

DELIMITER $$ 

DROP FUNCTION IF EXISTS `countSequenceBreaks`$$ 

CREATE FUNCTION `countSequenceBreaks`(`sequence` VARCHAR(1000)) 
RETURNS INT 
DETERMINISTIC 
BEGIN 
DECLARE `delimiter` CHAR DEFAULT ','; 

DECLARE `current`, `last` INT; 
DECLARE `result` INT DEFAULT 0; 

IF 
    `sequence` IS NULL 
    OR 
    NOT LENGTH(`sequence`) 
    OR 
    NOT INSTR(`sequence`, `delimiter`) 
THEN RETURN `result`; 
END IF; 

SET `current` = SUBSTRING_INDEX(`sequence`, `delimiter`, 1); 
SET `last`  = SUBSTRING_INDEX(`sequence`, `delimiter`, -1); 

IF `last` < `current` 
THEN 
    SET `result` = `last`; 
    SET `last`  = `current`; 
    SET `current` = `result`; 
    SET `result` = 0; 
END IF; 

WHILE `current` < `last` DO 
    IF NOT FIND_IN_SET(`current`, `sequence`) 
    THEN SET `result` = `result` + 1; 
    END IF; 

    SET `current` = `current` + 1; 
END WHILE; 

RETURN `result`; 
END$$ 

DELIMITER ; 

하지만 WHILE -loop 다른 시퀀스 회원들과 원인 쿼리 둔화 너무 많이 반복 걸릴 수 있습니다에 대한 걱정.

질문 :

  1. 는 저장 기능을 향상시킬 수있는 방법이 있습니까?
  2. 방법이 있다면 어떻게됩니까?

내 디버그 쿼리 : 그것은 결과 집합의

SELECT 
    `no`, `sequence`, `countSequenceBreaks`(`sequence`) 
FROM 
    (
     SELECT 1 as `no`, NULL as `sequence` 
     UNION ALL 
     SELECT 2, '' 
     UNION ALL 
     SELECT 3, '1' 
     UNION ALL 
     SELECT 4, '1,2,3,4,5' 
     UNION ALL 
     SELECT 5, '2,4,5' 
     UNION ALL 
     SELECT 6, '1, 5' 
     UNION ALL 
     SELECT 7, '1,3,5' 
    ) as `sub`; 

:

no sequence `countSequenceBreaks`(`sequence`) 
----------------------------------------------- 
1 NULL  0 
2    0 
3 1   0 
4 1,2,3,4,5 0 
5 2,4,5  1 
6 1,5  3 
7 1,3,5  2 

감사합니다.

답변

1

당신은 하나 개의 간단한 쿼리를 수행 할 수 있습니다

select sequence, 
CASE WHEN NOT INSTR(IFNULL(sequence,''), ',') THEN 0 
    ELSE 
     (
     SUBSTRING_INDEX(sequence,',' ,-1) 
     -SUBSTRING_INDEX(sequence,',' , 1) 
     ) 
     - 
     (LENGTH(sequence)-LENGTH(REPLACE(sequence,',',''))) 
END countSequenceBreaks 

from t 

방법 시퀀스 휴식의 수를 찾는 방법은?

예를 들어 1,3,5 시퀀스의 경우.

중단 횟수는 누락 된 구분 기호의 수를 계산하는 것입니다. 이 경우 전체 문자열 1,2,3,4,55-1=4 구분 기호를 포함하지만 휴식의 수 있도록 1,3,5 순서 만이 구분 기호를 포함 -

= 4-2 = 2 어떻게 구분 기호의 수를 알고 (놓친 자리 당신이 볼 수있는 동일 무엇을 놓친 구분 기호의 계산) 문자열에? 구분 기호가 (LENGTH(sequence)-LENGTH(REPLACE(sequence,',',''))

SQLFiddle demo

+0

감사 인 하나 개의 심볼 길이를 가지고 우리의 경우

... 당신은 genious입니다! – BlitZ