根据两个表中的主键计算列中匹配数据的数量

时间:2014-09-18 05:01:45

标签: sql plsql

我有两张表,结构相同,数据有些相同。例如,让我们考虑以下表格。

表格小册子

id | name   | dept | rollno
1  | Mark   | A    | 4
2  | Michael| B    | 5
3  | Norman | C    | 6
4  | Paul   | D    | 7
5  | Robert | E    | 8

表格

id | name   | dept | rollno
1  | Mark   | A    | 4
2  | Michael| B    | 5
3  | Norman | G    | 7
4  | Paul   | D    | 8
5  | Bradley| F    | 9

现在,等同于' id'在这两个表之间,我想得到各种列匹配的计数(name / dept / rollno),即0列匹配的行,1列匹配的行,2列匹配的行和相同的记录(包含所有匹配项的行)。

例如,给定数据的结果可以显示为

column_matches| count
0             | 1
1             | 1
2             | 1
3             | 2

我在Oracle10g上。关于如何解决这个问题的任何想法都会非常有用。

2 个答案:

答案 0 :(得分:2)

如果不测试此查询,我希望这有用:

SELECT ccols, COUNT(*)
  FROM(
       SELECT CASE WHEN p.name = s.name THEN 1 ELSE 0 END +
              CASE WHEN p.dept = s.dept THEN 1 ELSE 0 END +
              CASE WHEN p.roolno = s.rollno THEN 1 ELSE 0 END ccols
         FROM prim p
         JOIN sec  s
           ON p.id = s.id
      )
 GROUP
    BY ccols;

答案 1 :(得分:1)

@DirkNM您提供的解决方案确实非常适合@Ankur面临的具体情况。

然而,更通用的方法是使用一个过程。

以下是比较两个表数据(具有完全相同的结构)的通用过程的脚本。

/*
Author: Kasim Husaini
Creation Data: 18th Sept 2014
Description: Procedure to compare two tables and giving matching column count as a result set.
*/
Create PROCEDURE USP_COMPARE_TABLES(@P_PRI_TABLE VARCHAR(255)
    , @P_SEC_TABLE VARCHAR(255)
    , @P_PRIMARY_COL VARCHAR(255)
    ) AS
    BEGIN
        Declare @M_SQL VARCHAR(MAX)='';
        Declare @M_COL_COMPARE VARCHAR(MAX)='';
        Declare @M_SUB_QUERY VARCHAR(MAX)='';
        Declare @M_COMPARE_TEMPLATE VARCHAR(1000);
        Set @M_SQL='SELECT COL_COUNT, COUNT(1) MATCHES FROM ($X$) A GROUP BY COL_COUNT';

        SET @M_COMPARE_TEMPLATE = ' CASE WHEN P.$T$ = S.$T$ THEN 1 ELSE 0 END $N$';

        Select @M_COL_COMPARE=REPLACE(STUFF((Select '+'+REPLACE(@M_COMPARE_TEMPLATE,'$T$',C.NAME) FROM SYS.COLUMNS C 
        WHERE C.OBJECT_ID=OBJECT_ID(@P_PRI_TABLE) Order BY C.NAME FOR Xml Path('')),1,1,'')
        ,'$N$',CHAR(13))

        SET @M_SUB_QUERY = 'SELECT (' + @M_COL_COMPARE + ') AS COL_COUNT FROM ' + @P_PRI_TABLE + ' P JOIN ' + @P_SEC_TABLE +' S ON P.$PC$=S.$PC$ ';

        SET @M_SUB_QUERY=REPLACE(@M_SUB_QUERY,'$PC$',@P_PRIMARY_COL);

        SET @M_SQL=REPLACE(@M_SQL,'$X$',@M_SUB_QUERY);
        PRINT @M_SQL;
        Exec(@M_SQL);
    END