Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用重复值规范化MySQL表_Mysql_Sql_Database - Fatal编程技术网

如何使用重复值规范化MySQL表

如何使用重复值规范化MySQL表,mysql,sql,database,Mysql,Sql,Database,我有两张水果和颜色的桌子 在水果表中,cid列引用颜色表中的c_id,但问题是颜色表具有重复的颜色名称: MySQL中是否有一种有效的方法来删除重复的颜色行,并相应地更新foods表中的cid,从而得到如下结果 您可以得到一个结果集,该结果集具有每个f\u id的最小匹配颜色cid SELECT fruit.f_id, fruit.f_name, min(c2.c_id) as c_id FROM fruit INNER JOIN color c1 ON fruit.cid =

我有两张水果和颜色的桌子

在水果表中,
cid
列引用颜色表中的
c_id
,但问题是颜色表具有重复的颜色名称:

MySQL中是否有一种有效的方法来删除重复的颜色行,并相应地更新foods表中的
cid
,从而得到如下结果


您可以得到一个结果集,该结果集具有每个
f\u id的最小匹配颜色
cid

SELECT fruit.f_id, fruit.f_name, min(c2.c_id) as c_id
FROM
    fruit
    INNER JOIN color c1 ON fruit.cid = c1.c_id
    INNER JOIN color c2 ON cl.c_name = c2.c_name
GROUP BY fruit.f_id, fruit.f_name
这不是最有效的查询,但它可以工作。您可以使用此选项将
水果
表格设置为正确,以便在存在重复项时仅引用单个
颜色

修复
水果
表后,您可以运行查询查看哪些颜色未使用,以便知道要删除的内容:

SELECT color.*
FROM color
  LEFT OUTER JOIN fruit on color.c_id = fruit.cid
WHERE fruit.f_id IS NULL

您可以得到一个结果集,其中每个
f_id

SELECT fruit.f_id, fruit.f_name, min(c2.c_id) as c_id
FROM
    fruit
    INNER JOIN color c1 ON fruit.cid = c1.c_id
    INNER JOIN color c2 ON cl.c_name = c2.c_name
GROUP BY fruit.f_id, fruit.f_name
这不是最有效的查询,但它可以工作。您可以使用此选项将
水果
表格设置为正确,以便在存在重复项时仅引用单个
颜色

修复
水果
表后,您可以运行查询查看哪些颜色未使用,以便知道要删除的内容:

SELECT color.*
FROM color
  LEFT OUTER JOIN fruit on color.c_id = fruit.cid
WHERE fruit.f_id IS NULL

您可以通过以下步骤实现此目标-

1。删除重复项-

DELETE FROM colors C1
WHERE EXISTS (SELECT 1
              FROM colors C2
              WHERE C2.c_name = C1.c_name
              AND C2.c_id > C1.c_id);
UPDATE colors C1
JOIN
(
    SELECT @rownum:=@rownum+1 rownum, c_id, c_name
    FROM colors
    CROSS JOIN (select @rownum := 0) rn
) AS C2 ON C1.c_name = C2.c_name
SET C1.c_id = C2.rownum
2。重置c_id-

DELETE FROM colors C1
WHERE EXISTS (SELECT 1
              FROM colors C2
              WHERE C2.c_name = C1.c_name
              AND C2.c_id > C1.c_id);
UPDATE colors C1
JOIN
(
    SELECT @rownum:=@rownum+1 rownum, c_id, c_name
    FROM colors
    CROSS JOIN (select @rownum := 0) rn
) AS C2 ON C1.c_name = C2.c_name
SET C1.c_id = C2.rownum

您可以通过以下步骤实现此目标-

1。删除重复项-

DELETE FROM colors C1
WHERE EXISTS (SELECT 1
              FROM colors C2
              WHERE C2.c_name = C1.c_name
              AND C2.c_id > C1.c_id);
UPDATE colors C1
JOIN
(
    SELECT @rownum:=@rownum+1 rownum, c_id, c_name
    FROM colors
    CROSS JOIN (select @rownum := 0) rn
) AS C2 ON C1.c_name = C2.c_name
SET C1.c_id = C2.rownum
2。重置c_id-

DELETE FROM colors C1
WHERE EXISTS (SELECT 1
              FROM colors C2
              WHERE C2.c_name = C1.c_name
              AND C2.c_id > C1.c_id);
UPDATE colors C1
JOIN
(
    SELECT @rownum:=@rownum+1 rownum, c_id, c_name
    FROM colors
    CROSS JOIN (select @rownum := 0) rn
) AS C2 ON C1.c_name = C2.c_name
SET C1.c_id = C2.rownum

假设表之间存在外键约束,首先需要
update
table
fruit
。为此,您可以
join
表以获取颜色名称,然后使用相关子查询检索该颜色的最小
c_id

update fruit f
inner join color c on f.cid = c.c_id
set f.cid = (select min(c_id) from color c1 where c1.name = c.c_name)
然后您可以安全地删除重复的
颜色
s,同时保留具有最低
c_id的颜色

delete c
from color c
inner join color c1 on c1.c_name = c.c_name and c1.c_id < c.c_id
删除c
从c色开始
c1.c_名称上的内部连接颜色c1=c.c_名称和c1.c_id
假设表之间存在外键约束,您首先需要
更新
水果
。为此,您可以
join
表以获取颜色名称,然后使用相关子查询检索该颜色的最小
c_id

update fruit f
inner join color c on f.cid = c.c_id
set f.cid = (select min(c_id) from color c1 where c1.name = c.c_name)
然后您可以安全地删除重复的
颜色
s,同时保留具有最低
c_id的颜色

delete c
from color c
inner join color c1 on c1.c_name = c.c_name and c1.c_id < c.c_id
删除c
从c色开始
c1.c_名称上的内部连接颜色c1=c.c_名称和c1.c_id
首先,您需要将水果更新为仅引用每个颜色名称中的一个:

UPDATE fruit AS f 
INNER JOIN color As c ON f.cid = c.c_id
INNER JOIN (SELECT c_name, MIN(c_id) AS firstCid FROM color GROUP BY c_name) AS firsts
ON c.c_name = firsts.c_name
SET f.c_id = firsts.firstCid
;
注意:这与GMB的答案类似,但不使用相关子查询

然后,复制品可以用这样的东西清理

DELETE 
FROM colors 
WHERE c_id NOT IN (
     SELECT MIN(c_id) 
     FROM colors 
     GROUP BY c_name
   )
然而,这也将保留未使用的颜色

MySQL通常不喜欢同时从同一个表中选择和删除的查询,因此它可能必须这样表达才能“欺骗”MySQL:


首先,您需要将水果更新为仅引用每个颜色名称中的一个:

UPDATE fruit AS f 
INNER JOIN color As c ON f.cid = c.c_id
INNER JOIN (SELECT c_name, MIN(c_id) AS firstCid FROM color GROUP BY c_name) AS firsts
ON c.c_name = firsts.c_name
SET f.c_id = firsts.firstCid
;
注意:这与GMB的答案类似,但不使用相关子查询

然后,复制品可以用这样的东西清理

DELETE 
FROM colors 
WHERE c_id NOT IN (
     SELECT MIN(c_id) 
     FROM colors 
     GROUP BY c_name
   )
然而,这也将保留未使用的颜色

MySQL通常不喜欢同时从同一个表中选择和删除的查询,因此它可能必须这样表达才能“欺骗”MySQL:


您可以对删除的每种颜色运行一个查询<代码>更新水果集cid='1',其中cid='7'
,然后从表中删除
c_id
7
。对每种颜色重复,直到没有重复,然后不要再重复(使
c_name
唯一)。如果是我的话,我会用PHP(我的经验)或其他语言来实现自动化,这将非常简单<代码>更新水果集cid='1',其中cid='7'
,然后从表中删除
c_id
7
。对每种颜色重复,直到没有重复,然后不要再重复(使
c_name
唯一)。如果是我,我会使用PHP(我的经验)或其他语言来自动完成这项工作,这将非常简单_name@Uueerdo当然有。固定的我想你是想加入c的c1和c2_name@Uueerdo当然有。固定的哎呀,谢谢你!更新查询工作正常,但删除查询抛出错误:“c”在此位置无效,应为:EOF’:“@Csaba:我更新了删除查询,请告诉我它现在是否工作得更好。现在代码看起来有效,但当我执行代码时,我得到:“表'c'被指定了两次,既作为'DELETE'的目标,又作为数据的单独来源”@Csaba:好的,我将其更改为
JOIN
ed查询。我对其进行了测试,似乎效果良好。谢谢!更新查询工作正常,但删除查询抛出错误:“c”“在此位置无效,应为:EOF':”@Csaba:我更新了删除查询,请告诉我它现在是否工作得更好。现在代码看起来有效,但当我执行我得到的代码时:“表'c'被指定了两次,既作为'delete'的目标,也作为数据的单独源”@Csaba:好的,我将其更改为
JOIN
ed查询。我对它进行了测试,结果似乎很好。如果
fruit.cid
有一个带有on-delete级联的外键约束,那么最终会删除很多fruit数据;如果它没有任何约束,像香蕉变黄这样的信息将需要手动复制。如果
fruit.cid
有一个带有on delete cascade的外键约束,那么最终将擦除大量水果数据;如果它没有任何约束,像香蕉变黄这样的信息需要手动复制