Mysql 需要复杂的SQL查询
我有一个表Mysql 需要复杂的SQL查询,mysql,Mysql,我有一个表people,其中包含givenName和gender字段。我想根据基于其他行的最佳猜测,用gender=NULL更新所有这些行。 也就是说,如果有以下行 "John", NULL "Jane", NULL "Sam", NULL "Alex", NULL "Jack", NULL "John", "male" "John", "male" "Jane", "female" "Sam", "female" "Sam", "male" "Alex", "female" 我希望进行以下更
people
,其中包含givenName
和gender
字段。我想根据基于其他行的最佳猜测,用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”),我假设
更新人员A,人员B设置A.gender=B.gender,其中A.givenName=B.givenName和A.gender为空,B.gender为非空
应该这样做…您可以通过选择一个具有非空值且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
Scais的报价稍微有点扭曲,我会根据你们整张桌子的更高概率来申请。很明显,你们只展示了一小部分样品。我会尝试得到一个每个名字的档案,并相应计数为男性和女性。这一结果应适用于失踪人员。例如,如果你的表中有“Jack”这个词,男性有85次,女性有2次(我实际上认识一位女性,她叫Jack,是Jackie的缩写),那么男性的“Jack”将被应用
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
现在,以类似于Scais的方式将其作为相关更新的基础。。另外,我们只想更新现有性别为空的地方,否则我们将更新所有人
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
我不确定是否有一个问题可以回答。首先,您需要按“givenname”和“性别(非空)”分组。。。在第二级组之后,只使用“givenname”和COUNT(*)=1(这意味着它不是男性/女性。在这之后,您的表中只有一张“性别名称地图,没有歧义”。@换句话说,这可能更容易(至少对人类读者和维护者而言)要创建具有非歧义名称的临时表?是的,我想是这样。否则,对于任何新的读卡器都将是火箭科学=)您的查询不会修改已设置了性别的行(即,将它们“设置”为已存在的值),但是,添加WHERE条件
和a.gender为NULL更好吗?或者这不重要,性能方面?(我也很困惑:t.name=a.name上的和中的a.name=t.name
是否应该修改名称匹配时的所有行…)。。(不考虑性别)应仅选择具有一种不同性别形式的名称null。。(在条件允许的情况下再次移动冗余)。。其中只有一种性别不为空。。不需要更新。。至于性能,我要说的是:在我的最后一个应用程序中,我在t
和a
中使用了一个计算名称substring\u index(substring\u index(name',1),'-',1)
,因此“约翰男孩”和“约翰罗斯”被视为“约翰”。为了正常工作,这需要我将count(gender)=1
条件替换为max(gender)=min(gender)