比较mysql中两个表之间的差异

与oracle差异一样:如何比较两个表? 除了在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查询。 不知道这可能是一个因素。

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 ) 

编辑:添加“周围的话:设置

您可以使用UNION手动构build交集。 如果你在两个表中都有一些唯一的字段,比如说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,并使用AND来连接它们(例如ID NOT IN(…)和OTHER_FIELD NOT IN(。 ..)等)

我在这个环节find了另一个解决scheme

 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 
  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 

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

基于Haim的回答,我创build了一个PHP代码来testing和显示两个数据库之间的所有差异。 如果在源数据库或testing数据库中存在表格,这也会显示出来。 你必须改变你的细节<>variables的内容。

 <?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!"; } } ?>