Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Đếm số ký tự duy nhất trong một chuỗi

Điều này là để giải trí phải không?

SQL là tất cả về xử lý tập hợp các hàng, vì vậy nếu chúng ta có thể chuyển đổi một 'từ' thành một tập hợp các ký tự dưới dạng hàng thì chúng ta có thể sử dụng các hàm 'nhóm' để làm những việc hữu ích.

Sử dụng 'công cụ cơ sở dữ liệu quan hệ' để thực hiện các thao tác ký tự đơn giản sẽ cảm thấy sai. Tuy nhiên, có thể trả lời câu hỏi của bạn chỉ với SQL không? Vâng, nó là ...

Bây giờ, tôi luôn có một bảng có một cột số nguyên có khoảng 500 hàng trong đó có chuỗi tăng dần 1 .. 500. Nó được gọi là 'số nguyên'. Nó là một bảng thực sự nhỏ được sử dụng nhiều nên nó được lưu vào bộ nhớ. Nó được thiết kế để thay thế from 'select 1 ... union ... văn bản trong các truy vấn.

Nó hữu ích để tạo các hàng tuần tự (bảng) của bất kỳ thứ gì mà bạn có thể tính toán dựa trên một số nguyên bằng cách sử dụng nó trong cross join (cũng như bất kỳ inner join ). Tôi sử dụng nó để tạo ngày trong một năm, phân tích cú pháp các chuỗi được phân tách bằng dấu phẩy, v.v.

Bây giờ, sql mid có thể được sử dụng để trả về ký tự tại một vị trí nhất định. Bằng cách sử dụng bảng 'số nguyên', tôi có thể 'dễ dàng' chuyển đổi một 'từ' thành một bảng ký tự với một hàng cho mỗi ký tự. Sau đó, sử dụng các chức năng 'nhóm' ...

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  

Đầu ra:

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

Lưu ý:Số hàng trong đầu ra là số ký tự khác nhau trong chuỗi. Vì vậy, nếu số lượng hàng đầu ra được đếm thì số lượng 'các chữ cái khác nhau' sẽ được biết.

Quan sát này được sử dụng trong truy vấn cuối cùng.

Truy vấn cuối cùng:

Điểm thú vị ở đây là chuyển các hạn chế 'số nguyên' 'nối chéo' (1 .. length (word)) thành 'nối' thực tế thay vì thực hiện trong where mệnh đề. Điều này cung cấp cho trình tối ưu hóa các manh mối về cách hạn chế dữ liệu được tạo ra khi thực hiện 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  

Đầu ra:

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

Bảng Word và Dữ liệu:

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);

Bảng số nguyên:phạm vi 1 .. 30 cho ví dụ này.

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. Kích hoạt MySQL trước khi Chèn giá trị Kiểm tra

  2. Tại sao STRAIGHT_JOIN lại cải thiện đáng kể truy vấn này và nó có ý nghĩa gì khi nó được viết sau từ khóa SELECT?

  3. Học câu lệnh đã chuẩn bị từ SELECT FROM WHERE

  4. Lược đồ mã hóa biểu tượng cảm xúc cuối cùng

  5. cách xuất bản trình cài đặt ứng dụng c # window