2009-06-04 150 views
46

oracle diff: how to compare two tables?相同,只不过在mysql中。比较mysql中两个表之间的差异

假设我有两张表格t1和t2,它们在布局上是相同的,但可能包含不同的数据。

什么是区分这两个表的最好方法?

更确切地说,我试图找出一个简单的SQL查询,告诉我,如果在T1从一个行的数据是从相应的行T2中的数据

看来我不同不能使用相交或减号。当我尝试

SELECT * FROM robot intersect SELECT * FROM tbd_robot 

我得到一个错误代码:

[错误代码:1064,SQL状态:42000]你在你的SQL语法 有一个错误;检查对应于你的MySQL服务器版本 为正确的语法在1号线

附近使用“SELECT * FROM tbd_robot”我做得不对语法手册?如果没有,是否有另一个我可以使用的查询?

编辑:此外,我通过免费版本的DbVisualizer查询。不知道这可能是一个因素。

回答

65

INTERSECT需要在MySQL效仿:

SELECT 'robot' AS `set`, r.* 
FROM robot r 
WHERE ROW(r.col1, r.col2, …) NOT IN 
     (
     SELECT * 
     FROM tbd_robot 
     ) 
UNION ALL 
SELECT 'tbd_robot' AS `set`, t.* 
FROM tbd_robot t 
WHERE ROW(t.col1, t.col2, …) NOT IN 
     (
     SELECT * 
     FROM robot 
     ) 

编辑:添加'周围的话说:设置

+1

真棒,谢谢!显然,我不需要“按部就班”的部分,但它现在的作品 – echoblaze 2009-06-04 13:38:54

53

您可以使用UNION手动构建交集。如果你在两个表中都有一些独特的字段,例如ID:

SELECT * FROM T1 
WHERE ID NOT IN (SELECT ID FROM T2) 

UNION 

SELECT * FROM T2 
WHERE ID NOT IN (SELECT ID FROM T1) 

如果没有独特的价值,你仍然可以扩展上面的代码来检查所有领域,而不是仅仅的ID,和使用,将它们连接(如ID NOT IN(。 ..)和OTHER_FIELD NOT IN(...)等)

+2

真棒的答案。 – 2012-06-08 01:58:56

+1

优雅的解决方案,@Roee Adler! – Chubaka 2016-10-17 23:31:19

+0

谢谢。这是行得通的。 – 2017-08-16 10:39:14

8

我发现基于海姆的回答在这个link

SELECT MIN (tbl_name) AS tbl_name, PK, column_list 
FROM 
(
    SELECT ' source_table ' as tbl_name, S.PK, S.column_list 
    FROM source_table AS S 
    UNION ALL 
    SELECT 'destination_table' as tbl_name, D.PK, D.column_list 
    FROM destination_table AS D 
) AS alias_table 
GROUP BY PK, column_list 
HAVING COUNT(*) = 1 
ORDER BY PK 
2

另一种解决方案,我创建一个PHP代码测试和显示所有两个数据库之间的差异。 如果在源数据库或测试数据库中存在表格,这也会显示。 你必须改变你的细节<>变量内容。

<?php 

    $User = "<DatabaseUser>"; 
    $Pass = "<DatabasePassword>"; 
    $SourceDB = "<SourceDatabase>"; 
    $TestDB = "<DatabaseToTest>"; 

    $link = new mysqli("p:". "localhost", $User, $Pass, ""); 

    if (mysqli_connect_error()) { 

     die('Connect Error ('. mysqli_connect_errno() .') '. mysqli_connect_error()); 

    } 

    mysqli_set_charset($link, "utf8"); 
    mb_language("uni"); 
    mb_internal_encoding("UTF-8"); 

    $sQuery = 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="'. $SourceDB .'";'; 

    $SourceDB_Content = query($link, $sQuery); 

    if (!is_array($SourceDB_Content)) { 

     echo "Table $SourceDB cannot be accessed"; 
     exit(0); 

    } 

    $sQuery = 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="'. $TestDB .'";'; 

    $TestDB_Content = query($link, $sQuery); 

    if (!is_array($TestDB_Content)) { 

     echo "Table $TestDB cannot be accessed"; 
     exit(0); 

    } 

    $SourceDB_Tables = array(); 
    foreach($SourceDB_Content as $item) { 
     $SourceDB_Tables[] = $item["TABLE_NAME"]; 
    } 

    $TestDB_Tables = array(); 
    foreach($TestDB_Content as $item) { 
     $TestDB_Tables[] = $item["TABLE_NAME"]; 
    } 
    //var_dump($SourceDB_Tables, $TestDB_Tables); 
    $LookupTables = array_merge($SourceDB_Tables, $TestDB_Tables); 
    $NoOfDiscrepancies = 0; 
    echo " 

    <table border='1' width='100%'> 
    <tr> 
     <td>Table</td> 
     <td>Found in $SourceDB (". count($SourceDB_Tables) .")</td> 
     <td>Found in $TestDB (". count($TestDB_Tables) .")</td> 
     <td>Test result</td> 
    <tr> 

    "; 

    foreach($LookupTables as $table) { 

     $FoundInSourceDB = in_array($table, $SourceDB_Tables) ? 1 : 0; 
     $FoundInTestDB = in_array($table, $TestDB_Tables) ? 1 : 0; 
     echo " 

    <tr> 
     <td>$table</td> 
     <td><input type='checkbox' ". ($FoundInSourceDB == 1 ? "checked" : "") ."></td> 
     <td><input type='checkbox' ". ($FoundInTestDB == 1 ? "checked" : "") ."></td> 
     <td>". compareTables($SourceDB, $TestDB, $table) ."</td> 
    </tr> 
     "; 

    } 

    echo " 

    </table> 
    <br><br> 
    No of discrepancies found: $NoOfDiscrepancies 
    "; 


    function query($link, $q) { 

     $result = mysqli_query($link, $q); 

     $errors = mysqli_error($link); 
     if ($errors > "") { 

      echo $errors; 
      exit(0); 

     } 

     if($result == false) return false; 
     else if ($result === true) return true; 
     else { 

      $rset = array(); 

      while ($row = mysqli_fetch_assoc($result)) { 

       $rset[] = $row; 

      } 

      return $rset; 

     } 

    } 

    function compareTables($source, $test, $table) { 

     global $link; 
     global $NoOfDiscrepancies; 

     $sQuery = " 

    SELECT column_name,ordinal_position,data_type,column_type FROM 
    (
     SELECT 
      column_name,ordinal_position, 
      data_type,column_type,COUNT(1) rowcount 
     FROM information_schema.columns 
     WHERE 
     (
      (table_schema='$source' AND table_name='$table') OR 
      (table_schema='$test' AND table_name='$table') 
     ) 
     AND table_name IN ('$table') 
     GROUP BY 
      column_name,ordinal_position, 
      data_type,column_type 
     HAVING COUNT(1)=1 
    ) A;  

     "; 

     $result = query($link, $sQuery); 

     $data = ""; 
     if(is_array($result) && count($result) > 0) { 

      $NoOfDiscrepancies++; 
      $data = "<table><tr><td>column_name</td><td>ordinal_position</td><td>data_type</td><td>column_type</td></tr>"; 

      foreach($result as $item) { 

       $data .= "<tr><td>". $item["column_name"] ."</td><td>". $item["ordinal_position"] ."</td><td>". $item["data_type"] ."</td><td>". $item["column_type"] ."</td></tr>"; 

      } 

      $data .= "</table>"; 

      return $data; 

     } 
     else { 

      return "Checked but no discrepancies found!"; 

     } 

    } 

?> 
4
select t1.user_id,t2.user_id 
from t1 left join t2 ON t1.user_id = t2.user_id 
and t1.username=t2.username 
and t1.first_name=t2.first_name 
and t1.last_name=t2.last_name 

尝试。这会比较你的表并找到所有匹配的对,如果有任何不匹配,则返回NULL。