我面对的是一个设计不当的数据库,该数据库具有非规范化的表X。该表X应该与另一个表Y具有N:M关系。
问题在于,这种关系当前为1:N,而到目前为止,在存在各种要关联的注册表的情况下,使用杰瑞操纵的解决方案是重复这些条目。
简化一下,我有这个:
| ID | TEXT | LOCATION_ID | | 1 | foo | 1 | | 2 | foo | 2 | | 3 | bar | 1 | | 4 | bar | 4 | | 5 | bar | 3 |
我必须对这张表进行归一化处理。因此,我的第一个想法是尝试获取成对的相似注册表。像这样的东西:
| a.ID | b.ID | | 1 | 2 | | 3 | 4 | | 3 | 5 |
做一点实验:
SELECT a.id, b.id FROM mytable AS a INNER JOIN mytable AS b ON a.text = b.text AND a.id != b.id GROUP BY a.id, b.id
这导致这样的问题:
| a.ID | b.ID | | 1 | 2 | | 2 | 1 | | 3 | 4 | | 3 | 5 | | 4 | 3 | | 4 | 5 | | 5 | 3 | | 5 | 4 |
两对重复。
经过一番挖掘,我意识到这种方法更有效:
SELECT a.id, b.id FROM mytable AS a INNER JOIN mytable AS b ON a.text = b.text AND a.id < b.id GROUP BY a.id, b.id
所以,我得到了这个:
| a.ID | b.ID | | 1 | 2 | | 3 | 4 | | 3 | 5 | | 4 | 5 |
但是我仍然需要摆脱最后一个寄存器。
仅在一侧分组,然后在另一侧分组MIN():
MIN()
SELECT MIN(a.ID) a, b.ID b FROM mytable a JOIN mytable b ON b.text = a.text AND b.ID > a.ID GROUP BY b.ID
在sqlfiddle上看到它。