MySQL:根据A和B表中的数据更新表A.

时间:2013-10-30 22:40:07

标签: mysql sql join sql-update

这是两张桌子。我想根据两个表中的信息更新(不要选择)第一个表。

第一个名为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条奥兰多而不是一条(给某些城市增加3行)。

2)选择下一个城市(第二个和最后一个城市) - HrodnaHrodna在allcities中只遇到过一次,因此我们不会向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

P.S。如您所见,Info2中的值取自同一城市的Info2。

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

我能解释清楚吗?

谢谢。

2 个答案:

答案 0 :(得分: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

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

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

答案 1 :(得分: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;

我个人觉得更容易阅读EXISTSNOT EXISTS而不是很多联接,但这是个人偏好,请选择。