【问题标题】:MySQL: update table A based on the data from both A and B tablesMySQL:根据 A 表和 B 表中的数据更新表 A
【发布时间】:2013-11-10 18:57:16
【问题描述】:

这里有两张表。我想根据两个表中的信息更新(不选择)第一个表。

第一个名为somecities的表:

Name - State - Country - Info1 - Info2
Orlando - FL - US - 123 -AAA
Hrodna - HV - BY - 890 -BBB

名为allcities的第二个表:

Name - State - Country - Info1
Orlando - FL - US - 123
Orlando - KY - US - 456
Orlando - WV - US - 789
Orlando - SW - SA - 333
Hrodna - HV - BY - 890
Minsk - MV - BY - 199

somecities 表中的任何一对(姓名、州、国家/地区)都在allcities 表中,如果重要的话。所以,allcities 表更大。

我想这样修改somecities:

1) 取第一行,取Orlando。在allcities 中遇到了 4 次。因此,制作 4 串 Orlando 而不是 1 串(将 3 行添加到某些城市)。

2) 下一个城市(第二个和最后一个)-Hrodna。 Hrodna 在所有城市中只遇到一次,因此我们不会向 somecities 添加任何行(添加零行)。

3) 对somecities 中的每一行执行此操作。

查询结果为更新后的somecities:

Name - State - Country - Info1 - Info2
Orlando - FL -  US     - 123   -  AAA
Orlando - KY -  US     - 456   -  AAA
Orlando - WV -  US     - 789   -  AAA
Orlando - SW -  SA     - 333   -  AAA
Hrodna  - HV -  BY     - 890   -  BBB

附:如您所见,Info2 中的值取自同一城市的 Info2。

可以在一个查询中完成吗?也将接受两个查询作为答案。

我解释清楚了吗?

谢谢。

【问题讨论】:

  • 你会想用 NOT EXISTS,我会敲一个 SQL Fiddle 例子
  • 听起来你想要INSERT 而不是UPDATE somecities 表。您想以任何方式更改现有行吗?
  • 你是对的。谢谢你指出。是的,现有行没有更改。所以我想通过插入几行来更新 somecities 表。

标签: mysql sql join sql-update


【解决方案1】:

您可以使用NOT EXISTS 来测试尚未在您的表中的记录,然后进行快速连接以从现有记录中获取 info2:

SQL Fiddle demo

INSERT INTO somecities (Name,State,Country,Info1, Info2)
SELECT data.Name,data.State,data.Country,data.Info1,inf.Info2
FROM (
    SELECT *
    FROM allcities a
    WHERE NOT EXISTS (SELECT * 
                      FROM somecities s 
                      WHERE s.name = a.name
                            AND s.state = a.state
                            AND s.country = a.country
                            AND s.info1 = a.info1
                     )
  ) data
  INNER JOIN (SELECT DISTINCT Name, Info2 FROM somecities) inf
    ON data.name = inf.name;

我个人觉得阅读EXISTS 和NOT EXISTS 比阅读大量连接更容易,但这是个人喜好,请自行选择。

【讨论】:

    【解决方案2】:

    你需要一个 INSERT 查询,你可以使用这样的东西:

    INSERT INTO somecities
    SELECT a.*, si.Info2
    FROM
      allcities a LEFT JOIN somecities s
      ON a.Name=s.Name AND a.State=s.State AND a.Country=s.Country
      INNER JOIN (SELECT DISTINCT Name, Info2
                  FROM somecities) si
      ON a.Name=si.Name
    WHERE
      s.Name IS NULL
    

    请看小提琴here。

    这将插入来自 allcities 的所有行,这些行不存在于 somecities(或具有相同名称但不同的州或国家/地区),因为我正在使用带有 WHERE s.Name IS NULL 的 LEFT JOIN。

    然后,我选择了某些城市中存在的城市名称和 Info2 列,并且我只对名称进行了 INNER JOIN,以便仅返回至少存在于某些城市中的行一次。

    【讨论】:

    • 似乎可行(刚刚做了几次测试,没有发现错误)。如果有人发现任何错误,请在这里告诉我。不管怎样,你让我很开心。非常感谢。您是如何在不到一周的时间内创建此查询的? :) 谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 2020-04-22
    • 1970-01-01
    • 2020-02-19
    • 2011-06-05
    相关资源
    最近更新 更多