Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Hitung jumlah karakter unik dalam sebuah string

Ini untuk bersenang-senang kan?

SQL adalah semua tentang pemrosesan kumpulan baris, jadi jika kita dapat mengubah 'kata' menjadi kumpulan karakter sebagai baris, maka kita dapat menggunakan fungsi 'grup' untuk melakukan hal-hal yang berguna.

Menggunakan 'mesin database relasional' untuk melakukan manipulasi karakter sederhana terasa salah. Namun, apakah mungkin menjawab pertanyaan Anda hanya dengan SQL? Ya itu...

Sekarang, saya selalu memiliki tabel yang memiliki satu kolom bilangan bulat yang memiliki sekitar 500 baris di dalamnya yang memiliki urutan menaik 1 .. 500. Ini disebut 'integerseries'. Ini adalah tabel yang sangat kecil yang banyak digunakan sehingga di-cache di memori. Ini dirancang untuk menggantikan from 'select 1 ... union ... teks dalam kueri.

Ini berguna untuk menghasilkan baris berurutan (tabel) dari apa pun yang dapat Anda hitung yang didasarkan pada bilangan bulat dengan menggunakannya dalam cross join (juga inner join ). Saya menggunakannya untuk menghasilkan hari selama setahun, menguraikan string yang dibatasi koma, dll.

Sekarang, sql mid fungsi dapat digunakan untuk mengembalikan karakter pada posisi tertentu. Dengan menggunakan tabel 'integerseries' saya dapat 'dengan mudah' mengubah 'Word' menjadi tabel karakter dengan satu baris per karakter. Kemudian gunakan fungsi 'grup'...

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  

Keluaran:

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

Catatan:Jumlah baris dalam output adalah jumlah karakter yang berbeda dalam string. Jadi, jika jumlah baris keluaran dihitung maka jumlah 'huruf yang berbeda' akan diketahui.

Pengamatan ini digunakan dalam kueri akhir.

Permintaan terakhir:

Hal yang menarik di sini adalah untuk memindahkan pembatasan 'cross join' 'integerseries' (1 .. length(word)) ke 'join' yang sebenarnya daripada melakukannya di where ayat. Ini memberikan petunjuk kepada pengoptimal tentang cara membatasi data yang dihasilkan saat melakukan 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  

Keluaran:

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

Tabel Kata dan 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);

Tabel bilangan bulat:rentang 1 .. 30 untuk contoh ini.

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL:Bagaimana cara menggunakan pembatas di pemicu?

  2. ProgrammingError:Objek SQLite yang dibuat di utas hanya dapat digunakan di utas yang sama

  3. Apa yang lebih efisien - menyimpan log dalam database atau file sql?

  4. mysql - memindahkan baris dari satu tabel ke tabel lainnya

  5. Kesalahan umum MySQL:"Mendapat kesalahan saat membaca paket komunikasi"