MySql-仅当存在没有最后一个“ s”的相同单词时,才替换以“ s”结尾的单词

时间:2019-06-13 12:13:36

标签: mysql sql

我正在尝试使这些词在不同文章中最常出现。但是,我遇到一个单词的复数形式和单数形式的问题。

Table : articles

Id     articles

1      <b>Augmentation du nombre de noyades : des pistes d’explications</b><u><br> </u><br/>Paris, le jeudi 12 juin 2019 - Les enquêtes Noyades menées depuis 2002 par Santé publique France ont pour objectifs de recenser l’ensemble des noyades (accidentelles ou non, suivies de décès ou non) et de décrire les caractéristiques des victimes et des circonstances de survenue de ces incidents à des fins de prévention. <br/>Cette enquête est réalisée par questionnaire auprès des services de secours du 1er juin au 30 septembre en France métropolitaine et en Outre-mer. <br/>La dernière enquête a permis de recenser, en 2018, 1 960 noyades dont 30% (597/1 960) ont été suivies de décès. Parmi l’ensemble de ces noyades, 84% (1 649/1 960) étaient d’origine accidentelle, 8% (149/1 960) intentionnelles (tentatives de suicide, suicide ou agression) et 8% (162/1 960) étaient d’origine inconnue. <br/>Les investigateurs se sont plus particulièrement penchés sur les 1 649 noyades accidentelles (dont 25% à l’origine de décès) ces événements ayant augmenté de 30% par rapport à l’enquête de 2015 (1 266) sans qu’on assiste pour autant à une hausse des décès (entre 400 à 500 en moyenne chaque année). <br/><b>La canicule sur le banc des accusés</b><br/>Un premier facteur d’explication de cette forte augmentation des noyades « <i>est le contexte de fortes chaleurs durant la période de l’enquête</i> » soulignent les auteurs de ces travaux publiés dans le Bulletin épidémiologique hebdomadaire. Une étude canadienne a ainsi déjà montré que, sur la période 1999-2009, les températures excédant 30 °C étaient associées à une augmentation de 69% du risque de noyade en extérieur. Or, l’été 2018 a été classé par Météo-France comme le deuxième été le plus chaud depuis 1900. <br/><b>La noyade sèche : un concept faux qui fausse les chiffres</b><br/>Autre facteur explicatif pour les auteurs, la médiatisation depuis quelques années, et particulièrement depuis 2017, du concept de noyade «<i> sèche </i>» (noyade qui interviendrait plusieurs heures, voire plusieurs jours après une activité de baignade) qui ne repose sur aucune réalité scientifique mais qui a pu entraîner une sollicitation plus élevée des services de secours par des parents inquiets à la suite d’un début de noyade d’un enfant. <br/>Autre hypothèse, chez les moins de 6 ans, près des trois-quarts (73%) des noyades accidentelles ont eu lieu en piscine privée familiale. Or, la multiplication de piscines privées hors sol, dépourvues de système de sécurité pourrait être une explication à l’augmentation constatée. <br/><b>Un biais statistique ? </b><br/>Les auteurs soulignent en outre « <i>nous ne pouvons exclure que l’utilisation des données du réseau Oscour</i>® <i>pour la première fois lors de l’enquête 2018 ait pu entraîner une meilleure exhaustivité du recensement des noyades</i> ». Néanmoins, ils tempèrent « <i>Cependant, ceci ne pourrait expliquer qu’une faible partie de l’augmentation du nombre de noyades car lorsque la noyade n’était rapportée que par l’hôpital identifié par les données du réseau Oscour®, elle n’a pas été prise en compte car nous avons considéré que la victime n’avait pas été prise en charge par un service de secours organisé mais avait vraisemblablement été emmenée par un proche</i> ». <br/><b>Xavier Bataille</b></p>

我使用以下SQL查询:

select DISTINCT val, cnt as result from(
    select REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE((substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)),',',''),'.',''),'(',''),')',''),'!',''),'?',''),'%',''), '<b>', ' '), '</p>', ' '), '</b>', ' '), '<br/>', ''), '<br>', ''), ',', ' '), '<i>', ' '), '</i>', ' '), '.', ' '), '<u>', ' '), '</u>', ' '), '’', '\''), '*', ' '), '"', ' ') val,count(*) as cnt
    from articles t cross join(

         select a.n + b.n * 10 + c.n * 100 + 1 as n
          from (select 0 as n union all select 1 union all select 2 union all select 3 union all
                select 4 union all select 5 union all select 6 union all
                select 7 union all select 8 union all select 9
               ) a cross join
               (select 0 as n union all select 1 union all select 2 union all select 3 union all
                select 4 union all select 5 union all select 6 union all
                select 7 union all select 8 union all select 9
               ) b cross join
               (select 0 as n union all select 1 union all select 2 union all select 3 union all
                select 4 union all select 5 union all select 6 union all
                select 7 union all select 8 union all select 9
               ) c
        ) n
    where n.n <= 1 + (length(t.articles) - length(replace(t.articles, ' ', ''))) 
    AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) NOT REGEXP '^[0-9]+$' 
    AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) NOT REGEXP '>[^<]'
    AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) > ''
    AND (substring_index(substring_index(t.articles, ' ', n.n), ' ', -1)) NOT REGEXP '[0-9]' 
    AND CHAR_LENGTH((substring_index(substring_index(t.articles, ' ', n.n), ' ', -1))) > 2
    group by val 
    order by cnt desc
) as x 
ORDER BY `result`  DESC

SQL DEMO 我得到了什么:

val   result
des     15
noyades 10
...
noyade  6
...

我想要什么:

val   result
noyade  16
des     15
...

所以我的问题是:如何通过忽略最后一个's'来累积单词的复数形式和单数形式?  我只想替换以“ s”结尾的单词,只要存在没有最后一个“ s”的单词

1 个答案:

答案 0 :(得分:0)

让我们假设您只是为了清楚起见,将所有单词提取到名为 results 的单独表(可能是临时表)中,其中只有一列名为 word 。我建议在 word 列上建立索引。然后,以下SQL将起作用:

select word, count(*) from (
    select if (word in (
        /* all words such as 'noyades' such that 'noyade' also exists */
        select distinct sq.word from (
          select word, REGEXP_REPLACE(word, '(.*)s', '$1') as edited_word from results
        ) sq
        join results on sq.edited_word = results.word
         where sq.word <> edited_word
    ), REGEXP_REPLACE(word, '(.*)s', '$1'), word) as word from results
) sq
group by word
order by count(*) desc
;

请参见the following DB-Fiddle