我在管理笔记时遇到了这个问题。我从总是INSERT
新音符和SELECT
最后一个音符的策略开始。请不要笑,我一定认为这是个好主意,但现在,该系统甚至还没有全面生产,大约一个月内已经插入了30万行。两年后,我的系统将失败。我需要合并重复的行。以下是我的notes
表的结构:
CREATE TABLE IF NOT EXISTS `ps_notes` (
`CodeNTE` int(11) NOT NULL AUTO_INCREMENT,
`CodePRS` int(11) NOT NULL,
`CodeXYZ` int(11) NOT NULL,
`Type` char(3) NOT NULL,
`Focus` char(3) NOT NULL,
`Texte` tinytext NOT NULL,
`Date` datetime NOT NULL,
PRIMARY KEY (`CodeNTE`),
KEY `CodeXYZ` (`CodeXYZ`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=335068 ;
音符可以与人CodePRS
相关,也必然与Type
、Focus
和CodeXYZ
相关。他们有一个Texte
条目,有时我想知道Date
。
CodeXYZ
是注释所附实体的唯一标识符。该标识符可以来自任何表,因此不是绝对唯一的,因此出现了Type
字段。此字段指定父行来自哪个表。CCD_ 12字段区分引用相同CCD_ 13和CCD_ 14的注释。
这里有一些样品线:
+---------+------+-------+-------------+------------+|代码XYZ |类型|焦点|文本|日期|+---------+------+-------+-------------+------------+|30008|ctr|adm|Whatever|2013-05-09||30008|ctr|adm|Whatever|2013-06-10||30008|ctr|adm|Lorem ipsum|2013-06-11||30008|ctr|clt|他很酷|0000-00-00||2546|ctr|sup|另一个|2013-02-11||2546|ctr|sup|另一个|2013-02-11||2546|ctr|sup|另一个|2013-02-19|+---------+------+-------+-------------+------------+
这是我想要的输出:
+---------+------+-------+-------------+-----------------------------------------+
| CodeXYZ | Type | Focus | Texte | Date |
+---------+------+-------+-------------+-----------------------------------------+
| 30008 | ctr | adm | Lorem ipsum | 2013-06-11 (I want the most recent one) |
| 30008 | ctr | clt | He's cool | 0000-00-00 |
| 2546 | ctr | sup | Another | 2013-02-11 |
| 2546 | ctr | sup | Another | 2013-02-19 |
+---------+------+-------+-------------+-----------------------------------------+
合并条件
- 当
Focus
不是'sup'时,我想合并具有相同CodeXYZ
、Type
和Focus
的行 - 当
Focus
为"sup"时,我想合并具有相同CodeXYZ
、Type
、Focus
和Date
的行 - 我总是想保留最新的
所以我运行这个查询来合并临时表中的行:
INSERT INTO notes_tmp (CodePRS,CodeXYZ,Type,Focus,Texte,Date)
SELECT CodePRS,CodeXYZ,Type,Focus,Texte,Date
FROM notes
GROUP BY CodeXYZ,Type,Focus
但这样,所有的行都将被合并,即使是最后一行。
所以我想到了这个:
INSERT INTO notes_tmp (CodePRS,CodeXYZ,Type,Focus,Texte,Date)
SELECT CodePRS,CodeXYZ,Type,Focus,Texte,Date
FROM notes
WHERE Focus<>'sup'
GROUP BY CodeXYZ,Type,Focus
ORDER BY Date DESC
UNION
SELECT CodePRS,CodeXYZ,Type,Focus,Texte,Date
FROM notes
WHERE Focus='sup'
GROUP BY CodeXYZ,Type,Focus,Date
ORDER BY Date DESC
但是UNION不在正确的位置,我认为我不能在INSERT INTO ... SELECT
sql语法中使用它
有没有一种方法可以管理在一个mysql调用中复制这些行,其中多个子查询都根据不同的条件出现在同一个表中
您可以使用group_concat
合并文本字段,并使其他列与group by
唯一。试试这个:
INSERT INTO notes_temp
SELECT CodeXYZ,Type, Focus,GROUP_CONCAT(Texte),Date
FROM notes WHERE Focus = 'sup'
GROUP BY CodeXYZ,Type, Focus,Date;
INSERT INTO notes_temp
SELECT CodeXYZ,Type, Focus,GROUP_CONCAT(Texte),MAX(Date)
FROM notes WHERE Focus <> 'sup'
GROUP BY CodeXYZ,Type, Focus;
检查sqlfiddle
因此,有了@Volkan答案的一部分,我可以想出这个奇怪的sql来从我的GROUP_CONCT()中获得正确的注释
案例将获得组concat的最后一个条目。我使用了另一个分隔符(,,),因为逗号在文本中经常出现。连续三个稍微少一点。
INSERT INTO notes_temp
SELECT CodeXYZ,Type, Focus,Texte,Date
FROM notes WHERE Focus = 'sup'
GROUP BY CodeXYZ,Type, Focus,Date;
INSERT INTO notes_temp
SELECT
CodeXYZ,
Type,
Focus,
CASE
WHEN COUNT(Texte) > 1
THEN SUBSTR(GROUP_CONCAT(Texte SEPARATOR ",,,"),((LENGTH(GROUP_CONCAT(Texte SEPARATOR ",,,"))+2) - INSTR(REVERSE(GROUP_CONCAT(Texte SEPARATOR ",,,")),",,,")))
ELSE
Texte
END
AS Texte,
MAX(Date)
FROM notes WHERE Focus <> 'sup'
GROUP BY CodeXYZ,Type, Focus;