首页 > 解决方案 > 是否有任何“差异”机制来计算行差异?

问题描述

我有一个巨大的表格,其中包含大量相似之处细微差别的数据块。我想知道,与命令类似diff,我是否可以计算deltas这些块的(差异)(相对于前一个块或第一个块,比方说)并优雅地只存储添加/缺失的行。例如:

+-------+-------+------+
| Block | Order | Data |
+-------+-------+------+
|     1 |     1 |    A |
|     1 |     2 |    B |
|     1 |     3 |    C |
|     1 |     4 |    D |
+-------+-------+------+
|     2 |     1 |    A |
|     2 |     2 |    B |
|     2 |     3 |    D | <- missing 'C'
+-------+-------+------+
|     3 |     1 |    A |
|     3 |     2 |    B |
|     3 |     3 |    C |
|     3 |     4 |    D |
|     3 |     5 |    E | <- extra 'E'
+-------+-------+------+

这样,我只需要为 block和for block存储类似--order=4(missing C) 的东西。一种机制可以节省数百 MB 的重复次数。这有可能吗?2++after=4 order=5 'E'3diff

先感谢您!

标签: mysqlsql

解决方案


您应该能够根据您的情况进行调整:首先,复制您的示例(使用额外的块,以帮助确认我的测试)

CREATE TABLE IF NOT EXISTS `blocks` (
  `block` int(6) unsigned NOT NULL,
  `seq` int(3) unsigned NOT NULL,
  `content` varchar(200) NOT NULL,
  PRIMARY KEY (`block`,`seq`)
) DEFAULT CHARSET=utf8;
INSERT INTO `blocks` (`block`, `seq`, `content`) VALUES
  (1, 1, 'A'),
  (1, 2, 'B'),
  (1, 3, 'C'),
  (1, 4, 'D'),
  (2, 1, 'A'),
  (2, 2, 'B'),
  (2, 3, 'D'),
  (3, 1, 'A'),
  (3, 2, 'B'),
  (3, 3, 'C'),
  (3, 4, 'D'),
  (3, 5, 'E'),
  (4, 1, 'A'),
  (4, 2, 'B'),
  (4, 3, 'D')  
 ;
CREATE TABLE IF NOT EXISTS `masterblock` (
  `seq` int(3) unsigned NOT NULL,
  `content` varchar(200) NOT NULL,
  PRIMARY KEY (`seq`)
) DEFAULT CHARSET=utf8;
INSERT INTO `masterblock` (`seq`, `content`) VALUES
  (1, 'A'),
  (2, 'B'),
  (3, 'C'),
  (4, 'D');

然后这个查询(如果你的数据库支持 FULL JOIN 语法,这无疑可以用更简单的形式编写):

SELECT b.block, b.seq, b.content, m.content AS mastercontent
FROM blocks b
LEFT JOIN masterblock m
ON b.seq = m.seq
WHERE m.content IS NULL
OR b.content <> m.content
UNION ALL
SELECT distinct b.block, m.seq, NULL, m.content FROM
masterblock m
INNER JOIN
blocks b
ON m.seq NOT IN (SELECT seq FROM blocks WHERE block = b.block) 
ORDER BY 1, 2

产生这个结果(在 SQLFiddle 上测试过)

SQL 输出


推荐阅读