sql >> Databáze >  >> RDS >> Mysql

Spočítat počet jedinečných znaků v řetězci

To je pro zábavu, že?

SQL je o zpracování sad řádků, takže pokud dokážeme převést „slovo“ na sadu znaků jako řádky, můžeme použít funkce „skupiny“ k užitečným věcem.

Používání „relačního databázového stroje“ k jednoduché manipulaci se znaky je špatné. Je přesto možné na vaši otázku odpovědět pouze pomocí SQL? Ano je...

Nyní mám vždy tabulku, která má jeden celočíselný sloupec, který má asi 500 řádků, které mají vzestupnou posloupnost 1...500. Říká se tomu 'integerseries'. Je to opravdu malá tabulka, která hodně používala, takže se ukládá do mezipaměti. Je navržen tak, aby nahradil from 'select 1 ... union ... text v dotazech.

Je to užitečné pro generování sekvenčních řádků (tabulek) čehokoli, co můžete vypočítat a které je založeno na celém čísle pomocí cross join (také jakékoli inner join ). Používám ho pro generování dnů za rok, analýzu řetězců oddělených čárkou atd.

Nyní sql mid funkci lze použít k vrácení znaku na danou pozici. Pomocí tabulky 'integerseries' mohu 'snadno' převést 'slovo' na tabulku znaků s jedním řádkem na znak. Poté použijte funkce 'skupiny'...

SET @word='Hello World';

SELECT charAtIdx, COUNT(charAtIdx)
FROM (SELECT charIdx.id,
    MID(@word, charIdx.id, 1) AS charAtIdx 
    FROM integerseries AS charIdx
    WHERE charIdx.id <= LENGTH(@word)
    ORDER BY charIdx.id ASC
    ) wordLetters
GROUP BY
   wordLetters.charAtIdx
ORDER BY charAtIdx ASC  

Výstup:

charAtIdx  count(charAtIdx)  
---------  ------------------
                            1
d                           1
e                           1
H                           1
l                           3
o                           2
r                           1
W                           1

Poznámka:Počet řádků ve výstupu je počet různých znaků v řetězci. Pokud se tedy spočítá počet výstupních řádků, bude znám počet „různých písmen“.

Toto pozorování je použito v závěrečném dotazu.

Poslední dotaz:

Zajímavým bodem je přesunout omezení 'integerseries' 'cross join' (1 .. length(word)) do skutečného 'join' spíše než to udělat v where doložka. To poskytuje optimalizátoru vodítko, jak omezit data vytvářená při join .

SELECT 
   wordLetterCounts.wordId,
   wordLetterCounts.word,   
   COUNT(wordLetterCounts.wordId) AS letterCount
FROM 
     (SELECT words.id AS wordId,
             words.word AS word,
             iseq.id AS charPos,
             MID(words.word, iseq.id, 1) AS charAtPos,
             COUNT(MID(words.word, iseq.id, 1)) AS charAtPosCount
     FROM
          words
          JOIN integerseries AS iseq
               ON iseq.id BETWEEN 1 AND words.wordlen 
      GROUP BY
            words.id,
            MID(words.word, iseq.id, 1)
      ) AS wordLetterCounts
GROUP BY
   wordLetterCounts.wordId  

Výstup:

wordId  word                  letterCount  
------  --------------------  -------------
     1  3333333333                        1
     2  1113333333                        2
     3  1112222444                        3
     4  Hello World                       8
     5  funny - not so much?             13

Tabulka slov a data:

CREATE TABLE `words` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `word` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
  `wordlen` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

/*Data for the table `words` */

insert  into `words`(`id`,`word`,`wordlen`) values (1,'3333333333',10);
insert  into `words`(`id`,`word`,`wordlen`) values (2,'1113333333',10);
insert  into `words`(`id`,`word`,`wordlen`) values (3,'1112222444',10);
insert  into `words`(`id`,`word`,`wordlen`) values (4,'Hello World',11);
insert  into `words`(`id`,`word`,`wordlen`) values (5,'funny - not so much?',20);

Tabulka celých čísel:rozsah 1 .. 30 pro tento příklad.

CREATE TABLE `integerseries` (
  `id` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci


  1. Nastavte možnost 9 v uložené proceduře SQL Server pomocí WinHttp.WinHttpRequest.5.1 pro TLS 1.2

  2. Zabezpečujete přípravu výpisů vaši databázi?

  3. Zrychlení počítání řádků v MySQL

  4. Proč je používání jednotkových testů skvělou investicí do vysoce kvalitní architektury