复制(更新)同一张表中的某些内容

时间:2019-03-08 18:20:35

标签: php mysql sql

我想更新下表(行和col_md)的值:

Current Data

| id  | id_cat | row  | col_md |
| --- | ------ | ---- | ------ |
| 1   | 1      | 1    | 4      |
| 2   | 1      | 2    | 5      |
| 3   | 1      | 3    | 5      |
| 4   | 2      | 1    | 3      |
| 5   | 2      | 2    | 4      |
| 6   | 2      | 2    | 4      |
| 7   | 3      | 1    | 12     |
| 8   | 3      | 1    | 12     |
| 9   | 3      | 2    | 3      |

这可能类似于下表。 (我希望在id_cat = 2&3的行中具有与id_cat = 1相同的行内容。)

Required Data

| id  | id_cat | row  | col_md |
| --- | ------ | ---- | ------ |
| 1   | 1      | 1    | 4      |
| 2   | 1      | 2    | 5      |
| 3   | 1      | 3    | 5      |
| 4   | 2      | 1    | 4      |
| 5   | 2      | 2    | 5      |
| 6   | 2      | 3    | 5      |
| 7   | 3      | 1    | 4      |
| 8   | 3      | 2    | 5      |
| 9   | 3      | 3    | 5      |

id_cat 2和3应该具有与id_cat = 1中相同的“行”和“ col_md”值。

我尝试过this这样的第一个答案:

UPDATE `myTable` AS t1 JOIN `myTable` AS t2 ON t2.id_cat=1
SET    t1.row = t2.row, t1.col_md = t2.col_md
WHERE  t1.id_cat = 2 or t1.id_cat=3;

但这会导致所有“行”列值等于1。

我做错了什么,做对的方式是什么?

编辑:

上面的表格只是使这个问题更易于理解的示例,但实际表格更大(4k行),并且:

  • id_cat = 1的“行”列可以有任何数字,而不是示例中的序列。
  • “ col_md”列也可以有任何数字。
  • 这就是为什么更新必须在id_cat!= 1“ row”和“ col_md”值中设置id_cat = 1“ row”和“ col_md”值的副本的原因。

如果仅MySQL无法做到这一点,那么 php 脚本也将很好。

3 个答案:

答案 0 :(得分:2)

在您提供的示例查询中,您正在使用t2.row更新t1.row。当您加入id_cat时,这将导致选择多个行来更新单个行,因此结果仅取第一行。

您真正想要的是在更新中建立一对一关系,因此需要在查询中进行的更改是在联接中添加匹配的行,并在SET中删除分配,就像这样:

UPDATE `myTable` AS t1 JOIN `myTable` AS t2 ON t2.id_cat=1 AND t1.row = t2.row
SET t1.col_md = t2.col_md
WHERE  t1.id_cat = 2 or t1.id_cat=3;

然后给出输出:

MariaDB [testart]> select * from myTable;
+------+--------+------+--------+
| id   | id_cat | row  | col_md |
+------+--------+------+--------+
|    1 |      1 |    1 |      4 |
|    2 |      1 |    2 |      5 |
|    3 |      1 |    3 |      5 |
|    4 |      2 |    1 |      4 |
|    5 |      2 |    2 |      5 |
|    6 |      2 |    3 |      5 |
|    7 |      3 |    1 |      4 |
|    8 |      3 |    1 |      4 |
|    9 |      3 |    2 |      5 |
+------+--------+------+--------+
9 rows in set (0.00 sec)

答案 1 :(得分:2)

当前能够实现所需结果的SQL查询。

SELECT t2.id_cat, t1.row, t1.col_md 
FROM (SELECT row, col_md from mytable WHERE id_cat=1) as t1 , mytable as t2 
GROUP BY t2.id_cat, t1.row, t1.col_md

上面将返回以下内容。

enter image description here

我建议与以上查询一起使用INSERT语句将记录放入新表中并删除旧表。

干杯!

已编辑...

代替更新表,替代方法是将所需的记录插入到新表中。 这可以通过以下四个步骤来实现

  1. 使用相同的文件名(id为Auto_Increment,id_cat,row,col_md)创建一个tmp表
  2. 使用此语句插入tmp表...

INSERT INTO tmp(id_cat, row, col_md) 
SELECT t2.id_cat, t1.row, t1.col_md 
	FROM (SELECT row, col_md from mytable WHERE id_cat=1) as t1 , mytable as t2 
	GROUP BY t2.id_cat, t1.row, t1.col_md

  1. 删除/重命名“ myTable”。
  2. 将“ tmp”表重命名为“ myTable”。

希望这可以达到目的...

干杯!

答案 2 :(得分:1)

仅仅告诉您要从哪个组获取数据还不够,您需要将id匹配到id。

根据您的情况t2.id 4 7 t1.id 1 t2.id 5 8 t1.id 2 t2.id 6 9 < / strong>到t1.id 3

SELECT @d := COUNT(*) FROM myTable WHERE id_cat = 1;

UPDATE `myTable` AS t1 
JOIN `myTable` AS t2 ON t2.id_cat=1 AND 
t2.id = IFNULL(NULLIF(t1.id MOD @d, 0), @d)
SET    t1.row = t2.row, t1.col_md = t2.col_md
WHERE  t1.id_cat = 2 or t1.id_cat=3;

@d保留id_cat = 1

的行数

我们将t1.id除以@d,然后将其余(MOD)与t2.id相匹配。

t1.id@d的倍数时,余数是0,我们必须将其与@d匹配

因此我们将0放入NULL,将NULL放入@d