更新具有相同ID

时间:2015-08-24 09:47:20

标签: mysql group-by row

我正在使用MaNGOS数据库。目前我已经拥有自己的身份,但我想使用官方一次。问题是我已经在我想要更新的数据库中获得了一些值。

我要更新的表格如下所示。

mysql> SELECT * FROM `character` LIMIT 10;
+----+---------------------------------+--------------+--------------+-------+
| id | char_name_de                    | char_name_en | id_new       | id_old|
+----+---------------------------------+--------------+--------------+-------+
|  1 |                                 | NULL         |            2 |  NULL |
|  2 | Abgesandter des Schattenhammers | NULL         |        18201 |  NULL |
|  3 | Abgesplittertes Skelett         | NULL         |        10478 |  NULL |
|  4 | Adept aus Scholomance           | NULL         |        10469 |  NULL |
|  5 | Aduscha                         | NULL         |        18204 |  NULL |
|  6 | Aggressiver Bluthund            | NULL         |         8922 |  NULL |
|  7 | Akolyt aus Scholomance          | NULL         |        10471 |  NULL |
|  8 | Akolyt der Schmetterschilde     | NULL         |         9045 |  NULL |
|  9 | Althena                         | NULL         |        18208 |  NULL |
| 10 | Amadelis                        | NULL         |        18209 |  NULL |
+----+---------------------------------+--------------+--------------+-------+
10 rows in set (0.00 sec)

我想做的事情: 替换" id" by" new_id"

问题: " id_new"不是某些多语言字符串的唯一原因。 我希望将它们匹配到一行,保存" id"进入" id_old",替换" id" by" id_new"并删除" id_new"。

这看起来像这样:

mysql> SELECT *
    -> FROM `character`
    -> WHERE id_new IN(
    -> SELECT id_new
    -> FROM `character`
    -> GROUP BY `character`.id_new
    -> HAVING COUNT(`character`.id_new) > 1
    -> )
    -> ORDER BY id_new ASC;
+-----+--------------------------+--------------+--------------+-------+
| id  | char_name_de             | char_name_en | id_new       | id_old|
+-----+--------------------------+--------------+--------------+-------+
| 258 | Natter                   | NULL         |         2914 |  NULL |
| 342 | Snake                    | NULL         |         2914 |  NULL |
| 290 | Rat                      | NULL         |         4075 |  NULL |
| 292 | Ratte                    | NULL         |         4075 |  NULL |
| 276 | Orakel der Hakkari       | NULL         |        11346 |  NULL |
| 152 | Hakkari Oracle           | NULL         |        11346 |  NULL |
| 148 | Gurubashi Warrior        | NULL         |        11355 |  NULL |
| 201 | Krieger der Gurubashi    | NULL         |        11355 |  NULL |
| 344 | Sohn von Hakkar          | NULL         |        11357 |  NULL |
| 347 | Son of Hakkar            | NULL         |        11357 |  NULL |
|  47 | Bloodseeker Bat          | NULL         |        11368 |  NULL |
|  51 | Blutsucherfledermaus     | NULL         |        11368 |  NULL |
| 560 | Molten Giant             | NULL         |        11658 |  NULL |
| 123 | Geschmolzener Riese      | NULL         |        11658 |  NULL |
| 545 | Flamewaker               | NULL         |        11661 |  NULL |
|  93 | Feuerschuppe             | NULL         |        11661 |  NULL |
| 546 | Flamewaker Priest        | NULL         |        11662 |  NULL |
|  94 | Feuerschuppenpriester    | NULL         |        11662 |  NULL |
| 553 | Lava Annihilator         | NULL         |        11665 |  NULL |
| 214 | Lavavernichter           | NULL         |        11665 |  NULL |
| 540 | Firelord                 | NULL         |        11668 |  NULL |
|  92 | Feuerlord                | NULL         |        11668 |  NULL |
| 543 | Flame Imp                | NULL         |        11669 |  NULL |
| 104 | Flammenwichtel           | NULL         |        11669 |  NULL |
| 536 | Core Hound               | NULL         |        11671 |  NULL |
| 194 | Kernhund                 | NULL         |        11671 |  NULL |
| 534 | Ancient Core Hound       | NULL         |        11673 |  NULL |
| 384 | Uralter Kernhund         | NULL         |        11673 |  NULL |
| 549 | Golemagg the Incinerator | NULL         |        11988 |  NULL |
| 129 | Golemagg der Verbrenner  | NULL         |        11988 |  NULL |
| 558 | Majordomo Executus       | NULL         |        12018 |  NULL |
| 240 | Majordomus Exekutus      | NULL         |        12018 |  NULL |
| 554 | Lava Elemental           | NULL         |        12076 |  NULL |
| 212 | Lavaelementar            | NULL         |        12076 |  NULL |
| 564 | Sulfuron Harbinger       | NULL         |        12098 |  NULL |
| 359 | Sulfuronherold           | NULL         |        12098 |  NULL |
| 541 | Firesworn                | NULL         |        12099 |  NULL |
|  90 | Feueranbeter             | NULL         |        12099 |  NULL |
| 557 | Lava Surger              | NULL         |        12101 |  NULL |
| 215 | Lavawoger                | NULL         |        12101 |  NULL |
| 556 | Lava Spawn               | NULL         |        12265 |  NULL |
| 211 | Lavabrut                 | NULL         |        12265 |  NULL |
| 297 | Razzashi Raptor          | NULL         |        14821 |  NULL |
| 301 | Razzashiraptor           | NULL         |        14821 |  NULL |
+-----+--------------------------+--------------+--------------+-------+
44 rows in set (0.23 sec)

如何解决: 这个Query可以做我想要的,但是有一个问题,MySQL不能更新你用于选择子查询的表。

UPDATE `character`
SET `character`.id_old =    (
    SELECT `character`.id
    FROM `character`
    GROUP BY `character`.id_new
    HAVING COUNT(`character`.id_new) > 1
    )
WHERE `character`.id_new IN (
    SELECT `character`.id_new
    FROM `character` 
    GROUP BY `character`.id_new
    HAVING COUNT(`character`.id_new) > 1
    );

所以我必须创建一个包含我需要的所有值的temp_table:

CREATE TABLE `tmp_character` (
    `id` INT(11) NULL DEFAULT NULL,
    `id_new` INT(11) NULL DEFAULT NULL
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;

并填写值:

INSERT INTO tmp_character (id, id_new)
SELECT id, id_new
FROM `character`
WHERE id_new IN(
    SELECT id_new
    FROM `character` 
    GROUP BY `character`.id_new
    HAVING COUNT(`character`.id_new) > 1
    )
ORDER BY id_new ASC;

现在我收到了这个查询:

UPDATE `character`
SET `character`.id_old =    (
    SELECT tmp_character.id
    FROM tmp_character
    GROUP BY tmp_character.id_new
    HAVING COUNT(tmp_character.id_new) > 1
    )
WHERE `character`.id_new IN (
    SELECT tmp_character.id_new
    FROM tmp_character 
    GROUP BY tmp_character.id_new
    HAVING COUNT(tmp_character.id_new) > 1
    );

现在出现问题:ERROR 1242(21000):子查询返回的行数超过1行 这是真的,我有22个不同的身份要更新,我有22个团体,不知道为什么它不会工作。

在此查询之后,我的表应如下所示:

+-----+--------------------------+--------------+--------------+-------+
| id  | char_name_de             | char_name_en | id_new       | id_old|
+-----+--------------------------+--------------+--------------+-------+
| 258 | Natter                   | NULL         |         2914 |  258  |
| 342 | Snake                    | NULL         |         2914 |  342  |
| 290 | Rat                      | NULL         |         4075 |  290  |
| 292 | Ratte                    | NULL         |         4075 |  292  |
| 276 | Orakel der Hakkari       | NULL         |        11346 |  276  |
| 152 | Hakkari Oracle           | NULL         |        11346 |  152  |
| 148 | Gurubashi Warrior        | NULL         |        11355 |  148  |
| 201 | Krieger der Gurubashi    | NULL         |        11355 |  201  |
| 344 | Sohn von Hakkar          | NULL         |        11357 |  344  |
| 347 | Son of Hakkar            | NULL         |        11357 |  347  |
+-----+--------------------------+--------------+--------------+-------+
.
.
.

现在" id_new"应该是这样的独特:

+-----+--------------------------+--------------+--------------+-------+
| id  | char_name_de             | char_name_en | id_new       | id_old|
+-----+--------------------------+--------------+--------------+-------+
| 258 | Natter                   | NULL         |         2914 |  258  |
| 290 | Rat                      | NULL         |         4075 |  290  |
| 276 | Orakel der Hakkari       | NULL         |        11346 |  276  |
| 148 | Gurubashi Warrior        | NULL         |        11355 |  148  |
| 344 | Sohn von Hakkar          | NULL         |        11357 |  344  |
+-----+--------------------------+--------------+--------------+-------+
.
.
.

现在我要删除列" id_new"得到我的决赛桌。

+-------+--------------------------+--------------+-------+
| id    | char_name_de             | char_name_en | id_old|
+-------+--------------------------+--------------+-------+
| 2914  | Natter                   | NULL         |  258  |
| 4075  | Rat                      | NULL         |  290  |
| 11346 | Orakel der Hakkari       | NULL         |  276  |
| 11355 | Gurubashi Warrior        | NULL         |  148  |
| 11357 | Sohn von Hakkar          | NULL         |  344  |
+-------+--------------------------+--------------+-------+
.
.
.

有人可以帮我修改我的查询以使其运行吗?我需要在突出显示之后修复查询"现在我已经得到了这个查询:",休息很简单,我自己得到它,我只是发布它背景我想要的东西结束。

1 个答案:

答案 0 :(得分:1)

这是我的脚本将值从id移动到id_old,其中我有多行:

<?php
  function executeQuery($dbConnection, $Query) {
    $result =  $dbConnection -> query($Query);
    return $result;
  }


  function openDB() {
  $dbConnection=  new mysqli($mServer, $mUser, $mPwd, $mDatabase);
    return $dbConnection;
  }

  // open Database
  $DBconnection=openDB();

  // 1st query
  $query="SELECT *
          FROM `character`
          WHERE id_new IN(
            SELECT id_new
            FROM `character`
            GROUP BY `character`.id_new
            HAVING COUNT(`character`.id_new) > 1
          )
          ORDER BY id_new ASC;";

  // send query to database
  $result=executeQuery($DBconnection, $query);
  $numRows=$result->num_rows;

  // as long as you've got rows
  for(;$numRows>0;$numRows--) {

    // go to next row
    $currentRow=$result->fetch_object();
    for($i=0;$i<2;$i++) {
      if($i==0) {
        // skip 1st line from each row which is doubled
        $currentRow=$result->fetch_object();
      }

      // delete 2nd line from each row which is doubled
      $id_new=$currentRow->id;
      $query="delete from `character`where id=" .$id_new .";";
      $result2=executeQuery($DBconnection, $query);
   }
  }


?>

这是第二个修改版本,如果一行加倍,将删除第二行。如果一行被摧毁或更多,它将无效!

 do{
    while ( scanner.hasNext() ) {
         String command = scanner.nextLine();
         System.out.println("line:"+command);
    }
 } while ( conditionFlag)

但正如我所说,这是一个肮脏的剧本!

它是如何工作的? 我在第二个查询中使用一个查询的一些值。我承诺它可以在没有PHP的情况下工作,但有时快速而肮脏的解决方案比一个需要几天的好的解决方案更好!

//关闭