2015-07-31 1 views
2

Мне нужно сравнить таблицы в двух базах данных и найти разницу в имени_ column_name, data_type, is_nullable, column_default. Я хочу, чтобы мой выход будетСравните таблицу структуры в двух разных базах данных и обратном разности

db1.table 
id | int | NOT_NULL | AUTO_INCREMEMT 
name | text | NOT_NULL | 
YYYY | text | NOT_NULL | 
ZZZZ | text | NOT_NULL | 

db2.table 
id | int | NOT_NULL | AUTO_INCREMEMT 
name | text | NOT_NULL | 
YYYY | text |   | 

Результат запроса я хочу

COLUMN_NAME | DATA_TYPE | IS_NULLABLE | COLUMN_DEFAULT 
------------|-----------|-------------|--------------- 
YYYY  | TEXT  | NOT_NULL | 
YYYY  | TEXT  |    | 
ZZZZ  | TEXT  | NOT_NULL | 

То, что я до сих пор.

(SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = 'table_1' AND table_schema = 'db1') 
UNION 
(SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = 'table_1' AND table_schema = 'db2') 

Результаты запроса я получаю

COLUMN_NAME | DATA_TYPE | IS_NULLABLE | COLUMN_DEFAULT 
------------|-----------|----------------|--------------- 
id   | INT  | NOT_NULL  | AUTO_INCREMEMT 
name  | TEXT  | NOT_NULL  |    
YYYY  | TEXT  | NOT_NULL  |    
YYYY  | TEXT  |    |    

Это приближается, но возвращает слишком много строк и показывать только столбцы в обеих таблицах. Например, он не отображает столбец ZZZZ, но он возвращает столбец YYYY дважды, как ожидалось.

ответ

1

Проблема

Это очень легко придумать решение, если проблема сужается до одного предложения, например; Я хотел бы получить уникальный набор частичных строк из <some table>, где пара столбцов либо <some pair>, либо <some other pair>.


С учетом предыдущего предложения мы можем быстро увидеть, что нам нужно;

  • Способ выбора строки, которые мы хотели бы получить (WHERE + IN)
  • Пути к группе непосредственно эквивалентным строкам вместе (GROUP BY)
  • Пути отфильтровать строки, которые появляются только один раз (HAVING + COUNT)


Решение

SELECT 
    table_schema, table_name, column_name, data_type, is_nullable, column_default 
FROM 
    information_schema.columns 
WHERE 
    (table_schema,table_name) IN (('db1','table_1'), ('db2','table_1')) 
GROUP BY 
    column_name, data_type, is_nullable, column_default 
HAVING 
    COUNT(*) = 1 

Результат

+--------------+------------+-------------+-----------+-------------+----------------+ 
| table_schema | table_name | column_name | data_type | is_nullable | column_default | 
+--------------+------------+-------------+-----------+-------------+----------------+ 
| db1   | table_1 | YYYY  | text  | NO   | NULL   | 
| db2   | table_1 | YYYY  | text  | YES   | NULL   | 
| db1   | table_1 | ZZZZ  | text  | NO   | NULL   | 
+--------------+------------+-------------+-----------+-------------+----------------+ 


Препараты

CREATE DATABASE db1; 
USE    db1; 

CREATE TABLE `table_1` (
    `id` INT NOT NULL AUTO_INCREMENT, 
    `name` TEXT NOT NULL, 
    `YYYY` TEXT NOT NULL, 
    `ZZZZ` TEXT NOT NULL, 
    PRIMARY KEY (`id`) 
); 
CREATE DATABASE db2; 
USE    db2; 

CREATE TABLE `table_1` (
    `id` INT NOT NULL AUTO_INCREMENT, 
    `name` TEXT NOT NULL, 
    `YYYY` TEXT, 
    PRIMARY KEY (`id`) 
); 
+0

Отличное объяснение процесса. Спасибо. – dmgd