2014-10-22 119 views
0

我正在尝试编写一个查询,该字符串给出两个字符串之间不匹配的字母总数。查找两个字符串之间不匹配的字母

例如,我已经给定的两个字符串

串1:詹姆斯的字符串2:Romeeo

我需要找出没有第二个字符串中的字母总数在第一个字符串中有匹配。

字母是

R,O,O-和e

(注意,第一个字符串只有一个E,所以在Romeeo额外的E不具有匹配在字符串1)。

总之,那些字母(R,O,O,以及e)在串1

不存在有没有去解决的Oracle SQL这个问题呢?

回答

2

有趣的益智游戏;)

使用分析功能COUNT()并通过划分到当前行,你实际上能够“为你的字母编号”:

SELECT letters, 
     COUNT(*) OVER (PARTITION BY letters ORDER BY n ROWS 
         BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) cnt FROM (
    --     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    SELECT SUBSTR('Jameess', LEVEL, 1) letters, LEVEL n FROM DUAL 
    CONNECT BY LEVEL <= LENGTH('Jameess') 
) 

生产这一结果:

LETTERS CNT 
J  1 -- first J 
a  1 -- first a 
e  1 -- first e 
e  2 -- second e 
m  1 -- ... 
s  1 
s  2 

做一次每个字符串,你只需要比较每个字母索引它自己的组:

SELECT s2.letters 
FROM (
    SELECT letters, 
     COUNT(*) OVER (PARTITION BY letters ORDER BY n ROWS 
         BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) cnt FROM (
    SELECT SUBSTR('Jameess', LEVEL, 1) letters, LEVEL n FROM DUAL 
    CONNECT BY LEVEL <= LENGTH('Jameess') 
) 
) S1 
RIGHT OUTER JOIN (
    SELECT letters, 
     COUNT(*) OVER (PARTITION BY letters ORDER BY n ROWS 
         BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) cnt FROM (
    SELECT SUBSTR('Romeeeeo', LEVEL, 1) letters, LEVEL n FROM DUAL 
    CONNECT BY LEVEL <= LENGTH('Romeeeeo') 
) 
) S2 
ON s1.letters = s2.letters AND s1.cnt = s2.cnt 
WHERE s1.cnt IS NULL 
-- ^^^^^^ 
-- change to `s2.cnt` to compare your strings the other way around 
-- and replace the RIGHT JOIN by a LEFT JOIN 
ORDER BY letters 

生产:

LETTERS 
R 
e 
e 
o 
o 

(出于测试目的,我添加了一些额外的eJameessRomeeeeo

+0

优秀的解决方案 – user311509 2014-10-22 15:58:19

-2

试试这个SQL查询

DECLARE @string1 VARCHAR(100)='Jamess' 
DECLARE @string2 VARCHAR(100)='Romeeo' 
DECLARE @Notmatchstring VARCHAR(100) 
SET @Notmatchstring ='' 
DECLARE @index INT 
DECLARE @count INT 

SET @count=1 
WHILE @count <= LEN(@string2) 
BEGIN 

    SET @index=CHARINDEX(SUBSTRING(@string2,@count,1),@string1,0) 

    IF(@index=0) 
    BEGIN 
    SET @Notmatchstring [email protected] +' '+SUBSTRING(@string2,@count,1) 
    END 
    IF(@index>0) 
    BEGIN 
    SET @string1=REPLACE(@string1,SUBSTRING(@string2,@count,1),'') 
    END 
    SET @[email protected]+1 
END 
SELECT @Notmatchstring as NotMatchingCharacter 
+1

这个问题清楚地表明,使用的数据库是Oracle,而不是SQL Server。 [SQL]标记是指结构化查询语言,而不是微软的SQL Server产品。 – 2014-10-22 11:11:23

1

在Oracle

SQL> WITH DATA AS 
    2 (SELECT 'Jamess' str1, 'Romeeo' str2 FROM dual 
    3 ), 
    4 data2 AS 
    5 (SELECT SUBSTR(str1, LEVEL, 1) str1 
    6 FROM DATA 
    7  CONNECT BY LEVEL <= LENGTH(str1) 
    8 ), 
    9 data3 AS 
10 (SELECT SUBSTR(str2, LEVEL, 1) str2 
11 FROM DATA 
12  CONNECT BY LEVEL <= LENGTH(str2) 
13 ) 
14 SELECT * FROM data3 WHERE str2 NOT IN 
15 (SELECT str1 FROM data2 
16 ) 
17 UNION ALL 
18 SELECT str2 
19 FROM data3 
20 WHERE str2 IN 
21 (SELECT str1 FROM data2 
22 ) 
23 GROUP BY str2 
24 HAVING COUNT(*)>1 
25/

S 
- 
R 
o 
o 
e 

SQL> 
0

问题被加上[plsql]所以我想一个PL/SQL的解决方案是为了:

DECLARE 
    stringA VARCHAR2(20) := 'Jamess'; 
    stringB VARCHAR2(20) := 'Romeeo'; 
    strDiff VARCHAR2(20); 

    FUNCTION find_unmatched(p1 IN VARCHAR2, p2 IN VARCHAR2) 
    RETURN VARCHAR2 
    IS 
    s1 VARCHAR2(32767) := p1; 
    s2 VARCHAR2(32767) := p2; 
    s3 VARCHAR2(32767); 
    c CHAR(1); 
    p NUMBER; 
    BEGIN 
    LOOP 
     c := SUBSTR(s2, 1, 1); 

     p := INSTR(s1, c); 
     IF p = 0 THEN -- c not found in s1: add to unmatched list and remove from s2 
     s3 := s3 || c; 
     s2 := SUBSTR(s2, 2); 
     ELSE -- c found in s1: remove from s1 and s2 
     s1 := SUBSTR(s1, 1, p-1) || SUBSTR(s1, p+1, LENGTH(s1)-p); 
     s2 := SUBSTR(s2, 2); 
     END IF; 

     IF s1 IS NULL OR s2 IS NULL THEN 
     EXIT; 
     END IF; 
    END LOOP; 

    RETURN s3; 
    END find_unmatched; 

BEGIN 
    strDiff := find_unmatched(stringA, stringB); 

    DBMS_OUTPUT.PUT_LINE('strDiff=''' || strDiff || ''''); 
END; 

分享和享受。

相关问题