需要复杂的SQL查询

时间:2017-02-11 11:43:19

标签: mysql

我有一个表people,其中包含givenNamegender等字段。我希望根据基于其他行的最佳猜测,使用gender=NULL更新所有这些行。 也就是说,如果有以下几行

"John", NULL
"Jane", NULL
"Sam", NULL
"Alex", NULL
"Jack", NULL
"John", "male"
"John", "male"
"Jane", "female"
"Sam", "female"
"Sam", "male"
"Alex", "female"

我想进行以下更改:

"John", "male"
"Jane", "female"
"Sam", NULL
"Alex", "female"
"Jack", NULL
...

因此,约翰被正确识别为男性,简为女性,而不清楚萨姆是萨曼莎还是塞缪尔。我知道我的方法的缺点(也就是说,Alex可能实际上是男性,而着名的男性名称Jack并不被认可),但我仍然想知道我的目标是否可以通过单个SQL查询来实现?

如果不是混合案例(例如“Sam”),我认为UPDATE people A, people B SET A.gender = B.gender WHERE A.givenName=B.givenName AND A.gender IS NULL and B.gender IS NOT NULL应该这样做......

2 个答案:

答案 0 :(得分:1)

您可以使用带有dinamically gerated表的select值,其值为not null = count = 1

  UPDATE  people A
  INNER JOIN  (select name, max(gender) gender
               from people 
               where gender is not null
               group by name
               having count(gender)=1 ) t   on t.name = a.name
  set a.gender = t.gender 

答案 1 :(得分:1)

Scais提议略有不同,我会根据你整张桌子的概率较高来申请。显然你只是展示了一个小样本。我会尝试获取一个存档的每个名字,相应的数字为男性和女性。结果应该适用于那些失踪的人。例如,如果你的桌子上有“杰克”,男性85次,女性2次(我实际上认识的是杰克的女性 - 杰克的缩写),“杰克”作为男性将被应用。

select
      p.name, 
      sum( case when p2.gender = 'male' then 1 else 0 end ) as maleCount,
      sum( case when p2.gender = 'female' then 1 else 0 end ) as femaleCount
   from 
      people p
         join people p2
            on p.name = p2.name
           AND p2.gender IS NOT NULL
   where 
      p.gender is null
   group by 
      p.name

现在,使用THAT作为相关更新的基础,与Scais类似。此外,我们只想更新现有性别IS NULL的位置,否则我们将更新EVERYONE。

UPDATE  people A
   INNER JOIN  (above query) t
      on t.name = a.name
   set a.gender = case when t.maleCount > t.femaleCount 
                       then 'male' else 'female' end
   where a.gender IS NULL