Mysql 合并具有相同值的sql行

Mysql 合并具有相同值的sql行,mysql,sql,Mysql,Sql,我已经在数据库中添加了一些数据,我刚刚发现我有很多重复项,当然有不同的键,我想把它们合并到一个记录中 我希望在sql数据库本身中执行此操作,我不希望截断表并再次插入值,而不会重复,因为脚本非常慢 以下是我的场景示例: 工作台轨道: key | artist | title ----|-----------|-------- k1 | artist1 | title1 ----|-----------|-------- k2 | artist1 | title1 ----|---

我已经在数据库中添加了一些数据,我刚刚发现我有很多重复项,当然有不同的键,我想把它们合并到一个记录中

我希望在sql数据库本身中执行此操作,我不希望截断表并再次插入值,而不会重复,因为脚本非常慢

以下是我的场景示例:

工作台轨道:

key |   artist  | title
----|-----------|--------
k1  |  artist1  | title1
----|-----------|--------
k2  |  artist1  | title1
----|-----------|--------
k3  |  artist1  | title1
key |   artist  | title
----|-----------|--------
k1  |  artist1  | title1
图表:

trackKey | otherKey |  anotherKey  |  value
---------|----------|--------------|---------
k1       |   ok1    |      ak4     |    v1
---------|----------|--------------|---------
k3       |   ok2    |      ak2     |    v2
---------|----------|--------------|---------
k1       |   ok3    |      ak9     |    v2
---------|----------|--------------|---------
k2       |   ok4    |      ak1     |    v6
trackKey | otherKey |  anotherKey  |  value
---------|----------|--------------|---------
k1       |   ok1    |      ak4     |    v1
---------|----------|--------------|---------
k1       |   ok2    |      ak2     |    v2
---------|----------|--------------|---------
k1       |   ok3    |      ak9     |    v2
---------|----------|--------------|---------
k1       |   ok4    |      ak1     |    v6
其中
chart.trackKey
引用
track.key

我希望达到的结果是:

工作台轨道:

key |   artist  | title
----|-----------|--------
k1  |  artist1  | title1
----|-----------|--------
k2  |  artist1  | title1
----|-----------|--------
k3  |  artist1  | title1
key |   artist  | title
----|-----------|--------
k1  |  artist1  | title1
图表:

trackKey | otherKey |  anotherKey  |  value
---------|----------|--------------|---------
k1       |   ok1    |      ak4     |    v1
---------|----------|--------------|---------
k3       |   ok2    |      ak2     |    v2
---------|----------|--------------|---------
k1       |   ok3    |      ak9     |    v2
---------|----------|--------------|---------
k2       |   ok4    |      ak1     |    v6
trackKey | otherKey |  anotherKey  |  value
---------|----------|--------------|---------
k1       |   ok1    |      ak4     |    v1
---------|----------|--------------|---------
k1       |   ok2    |      ak2     |    v2
---------|----------|--------------|---------
k1       |   ok3    |      ak9     |    v2
---------|----------|--------------|---------
k1       |   ok4    |      ak1     |    v6
这样,
轨迹
中相同条目的每个重复项都会合并到一行,
图表
中的旧关键点会更新为
轨迹
表格中唯一保留的关键点

在SQL中有没有办法做到这一点

编辑:

解决方案#1基于@popovitsj的答案

UPDATE chart c SET trackUri =
(WITH track_unique AS
(
    SELECT MIN(uri) AS key, artist, title, album. artwork FROM track
    GROUP BY artist, title
)
SELECT tu.key FROM chart c1
INNER JOIN track t ON c1.trackUri = t.key
INNER JOIN track_unique tu ON t.artist = tu.artist AND t.title = tu.title
WHERE c1.trackUri = c.trackUri and c1.countryId = c.countryId and c1.date = c.date);
返回

#1064 - Syntax error near 
'track_unique AS (
SELECT MIN(uri) AS key, artist, title, album. artwork FR' line 2 
解决方案#2基于@juergen d的答案

update chart
join track t1 on t1.uri = chart.trackUri
left join 
(
   select min(uri) as key
   from track 
   group by artist, title
) tmp_track on tmp_track.key = chart.trackUri
set trackkey = tmp_tbl.key
where chart.trackUri not in 
(
  select min(uri)
  from track
  group by artist, title
  having count(*) > 1
);
返回

#1064 - Syntax error near
   'key
   from track
   group by artist, title
) tmp_track on tmp_track.key = c' line 5 
我不知道我做错了什么,所以我添加了模式定义(取自phpMyAdmin)


第一个with子句获取要保留的id,然后在下一个select查询中将这些id与图表id匹配

我根据您对我原始答案的修改编辑了此答案。这个答案假设
图表(countryid,date)
唯一地标识一个图表,并且只有当
曲目(关键、艺术家、标题、专辑)
相等时,才能合并曲目

UPDATE chart c SET trackUri =
(WITH track_unique AS
(
    SELECT MIN(uri) AS key, artist, title, album, artwork FROM track
    GROUP BY artist, title, album, artwork
)
SELECT tu.key FROM chart c1
INNER JOIN track t ON c1.trackUri = t.key
INNER JOIN track_unique tu
ON t.artist = tu.artist
AND t.title = tu.title
AND t.album = tu.album
AND t.artwork = tu.artwork
WHERE c1.trackUri = c.trackUri
AND c1.countryId = c.countryId
AND c1.date = c.date);
要在执行此更新后删除剩余的重复项,请执行以下操作:

DELETE FROM track
WHERE uri NOT IN
    (SELECT MIN(uri) AS key, artist, title, album, artwork
     FROM track
     GROUP BY artist, title, album, artwork);

如果重复值是完全重复的,则可以使用

SELECT MIN(key),artist,title FROM track GROUP BY artist,title;

获取
曲目
表中数据的免费复制版本。您可以将其放在一个临时表中并交换它们,或者使用SQL客户端下载数据并重新导入数据,或者诸如此类——为了安全起见,我不会尝试在一个语句中完成所有操作…

图表的键由
(trackKey,otherKey,anotherKey)
track
的键是
URI
组成。你的代码仍然有效吗?是的,当然,这只会使查询稍微长一点。在你发布你的代码时,我编辑了第一条注释,请检查它。我不明白如果曲目的键是URI,这有什么关系。它仍然可以比较,所以
MIN()
应该可以工作。这会导致语法错误,这并不奇怪。试试我修改过的答案。如果你必须首先这么做,那肯定是一种代码味道。为什么会得到重复的API?因为我使用的API返回重复的API。每首曲目可能有一个不同的uri,这取决于发布的国家。这意味着曲目x在意大利专辑中有一个特定的uri,而在美国专辑中有一个不同的uri,但它仍然是同一首曲目,我需要做的是,这些都被认为是重复的。这个评论解释了真正发生的事情。这不是数据管理不当(又称代码气味)。这是因为您正在寻求将数据投影到不同的空间。“投影”是关系的基本操作之一,是整个关系系统的基础。不幸的是,投影需要时间,所以最好的答案是运行一段时间。如果您是DBA,您可能会发现在辅助表中具体化投影是值得的,但这本身就有一个包袱。