Bạn có thích phân tích cú pháp chuỗi không? Nếu vậy, một trong những hàm chuỗi không thể thiếu để sử dụng là SQL SUBSTRING. Đó là một trong những kỹ năng mà nhà phát triển cần có đối với bất kỳ ngôn ngữ nào.
Vì vậy, làm thế nào để bạn làm điều đó?
Các điểm quan trọng trong phân tích cú pháp chuỗi
Giả sử bạn chưa quen với phân tích cú pháp. Bạn cần nhớ những điểm quan trọng nào?
- Biết thông tin nào được nhúng trong chuỗi.
- Nhận vị trí chính xác của từng phần thông tin trong một chuỗi. Bạn có thể phải đếm tất cả các ký tự trong chuỗi.
- Biết kích thước hoặc độ dài của từng đoạn thông tin trong một chuỗi.
- Sử dụng hàm chuỗi phù hợp để có thể trích xuất từng phần thông tin trong chuỗi một cách dễ dàng.
Biết tất cả các yếu tố này sẽ giúp bạn chuẩn bị cho việc sử dụng SQL SUBSTRING () và chuyển các đối số cho nó.
Cú pháp SUBSTRING SQL
Cú pháp của SQL SUBSTRING như sau:
SUBSTRING (biểu thức chuỗi, bắt đầu, độ dài)
- biểu thức chuỗi - a chuỗi chữ hoặc một biểu thức SQL trả về một chuỗi.
- bắt đầu - một số mà quá trình trích xuất sẽ bắt đầu. Nó cũng dựa trên 1 - ký tự đầu tiên trong đối số biểu thức chuỗi phải bắt đầu bằng 1, không phải 0. Trong SQL Server, nó luôn là một số dương. Tuy nhiên, trong MySQL hoặc Oracle, nó có thể là tích cực hoặc tiêu cực. Nếu âm, quá trình quét sẽ bắt đầu từ cuối chuỗi.
- độ dài - độ dài của các ký tự cần trích xuất. SQL Server yêu cầu nó. Trong MySQL hoặc Oracle, nó là tùy chọn.
4 Ví dụ về SQL SUBSTRING
1. Sử dụng SQL SUBSTRING để trích xuất từ chuỗi văn bản
Hãy bắt đầu với một ví dụ đơn giản bằng cách sử dụng một chuỗi ký tự. Chúng tôi sử dụng tên của một nhóm nhạc nữ nổi tiếng của Hàn Quốc, BlackPink và Hình 1 minh họa cách hoạt động của SUBSTRING:
Đoạn mã dưới đây cho biết cách chúng tôi sẽ trích xuất nó:
-- extract 'black' from BlackPink (English)
SELECT SUBSTRING('BlackPink',1,5) AS result
Bây giờ, hãy cũng kiểm tra tập hợp kết quả trong Hình 2:
Nó có dễ dàng không?
Để giải nén Đen từ BlackPink , bạn bắt đầu từ vị trí 1 và kết thúc ở vị trí 5. Kể từ BlackPink là tiếng Hàn, hãy cùng tìm hiểu xem SUBSTRING có hoạt động trên các ký tự tiếng Hàn Unicode hay không.
( TUYÊN BỐ TỪ CHỐI :Tôi không thể nói, đọc hoặc viết tiếng Hàn, vì vậy tôi đã lấy bản dịch tiếng Hàn từ Wikipedia. Tôi cũng đã sử dụng Google Dịch để xem những ký tự nào tương ứng với Đen và Màu hồng . Xin hãy tha thứ cho tôi nếu điều đó sai. Tuy nhiên, tôi hy vọng rằng điểm tôi đang cố gắng làm rõ sẽ đến і ngang)
Hãy có chuỗi bằng tiếng Hàn (xem Hình 3). Các ký tự tiếng Hàn được sử dụng dịch sang BlackPink:
Bây giờ, hãy xem đoạn mã bên dưới. Chúng tôi sẽ trích xuất hai ký tự tương ứng với Đen .
-- extract 'black' from BlackPink (Korean)
SELECT SUBSTRING(N'블랙핑크',1,2) AS result
Bạn có nhận thấy chuỗi tiếng Hàn đứng trước N ? Nó sử dụng các ký tự Unicode và SQL Server giả định là NVARCHAR và phải được đặt trước N . Đó là điểm khác biệt duy nhất trong phiên bản tiếng Anh. Nhưng nó sẽ chạy tốt? Xem Hình 4:
Nó chạy mà không có lỗi.
2. Sử dụng SQL SUBSTRING trong MySQL với đối số bắt đầu phủ định
Có đối số bắt đầu phủ định sẽ không hoạt động trong SQL Server. Nhưng chúng ta có thể có một ví dụ về điều này bằng cách sử dụng MySQL. Lần này, chúng ta hãy trích xuất Pink từ BlackPink . Đây là mã:
-- Extract 'Pink' from BlackPink using MySQL Substring (English)
select substring('BlackPink',-4,4) as result;
Bây giờ, hãy có kết quả trong Hình 5:
Vì chúng ta đã truyền -4 cho tham số bắt đầu, nên quá trình trích xuất bắt đầu từ cuối chuỗi, lùi 4 ký tự. Để đạt được kết quả tương tự trong SQL Server, hãy sử dụng hàm RIGHT ().
Các ký tự Unicode cũng hoạt động với MySQL SUBSTRING, như bạn có thể thấy trong Hình 6:
Nó hoạt động tốt. Nhưng bạn có nhận thấy rằng chúng ta không cần đặt trước chuỗi bằng N không? Ngoài ra, lưu ý rằng có một số cách để lấy chuỗi con trong MySQL. Bạn đã thấy SUBSTRING. Các hàm tương đương trong MySQL là SUBSTR () và MID ().
3. Phân tích cú pháp các chuỗi con với các đối số bắt đầu và độ dài có thể thay đổi
Đáng buồn thay, không phải tất cả các trích xuất chuỗi đều sử dụng đối số bắt đầu và độ dài cố định. Trong trường hợp như vậy, bạn cần CHARINDEX để có được vị trí của một chuỗi mà bạn đang nhắm mục tiêu. Hãy lấy một ví dụ:
DECLARE @lineString NVARCHAR(30) = N'김제니 01/16/[email protected]'
DECLARE @name NVARCHAR(5)
DECLARE @bday DATE
DECLARE @instagram VARCHAR(20)
SET @name = SUBSTRING(@lineString,1,CHARINDEX('@',@lineString)-11)
SET @bday = SUBSTRING(@lineString,CHARINDEX('@',@lineString)-10,10)
SET @instagram = SUBSTRING(@lineString,CHARINDEX('@',@lineString),30)
SELECT @name AS [Name], @bday AS [BirthDate], @instagram AS [InstagramAccount]
Trong đoạn mã trên, bạn cần trích xuất tên bằng tiếng Hàn, ngày sinh và tài khoản Instagram.
Chúng ta bắt đầu với việc xác định ba biến để nắm giữ những thông tin đó. Sau đó, chúng ta có thể phân tích cú pháp chuỗi và gán kết quả cho từng biến.
Bạn có thể nghĩ rằng có các điểm bắt đầu và độ dài cố định thì đơn giản hơn. Bên cạnh đó, chúng ta có thể xác định chính xác nó bằng cách đếm các ký tự theo cách thủ công. Nhưng nếu bạn có nhiều thứ này trên bàn thì sao?
Đây là phân tích của chúng tôi:
- Mục cố định duy nhất trong chuỗi là @ nhân vật trong tài khoản Instagram. Chúng ta có thể lấy vị trí của nó trong chuỗi bằng cách sử dụng CHARINDEX. Sau đó, chúng tôi sử dụng vị trí đó để xem bắt đầu và độ dài của phần còn lại.
- Ngày sinh ở định dạng cố định sử dụng MM / dd / yyyy với 10 ký tự.
- Để trích xuất tên, chúng tôi bắt đầu từ 1. Vì ngày sinh có 10 ký tự cộng với @ ký tự, bạn có thể nhận được ký tự kết thúc của tên trong chuỗi. Từ vị trí của @ ký tự, chúng tôi quay lại 11 ký tự. SUBSTRING (@ lineString, 1, CHARINDEX (‘@’, @ lineString) -11) là con đường để đi.
- Để lấy ngày sinh, chúng tôi áp dụng logic tương tự. Nhận vị trí của @ và di chuyển lùi 10 ký tự để nhận giá trị bắt đầu ngày sinh. 10 là độ dài cố định. SUBSTRING (@ lineString, CHARINDEX (‘@’, @ lineString) -10,10) là cách lấy ngày sinh.
- Cuối cùng, việc tạo tài khoản Instagram rất đơn giản. Bắt đầu từ vị trí của @ ký tự sử dụng CHARINDEX. Lưu ý:30 là giới hạn tên người dùng Instagram.
Kiểm tra kết quả trong Hình 7:
4. Sử dụng SQL SUBSTRING trong câu lệnh SELECT
Bạn cũng có thể sử dụng SUBSTRING trong câu lệnh SELECT, nhưng trước tiên, chúng ta cần có dữ liệu hoạt động. Đây là mã:
SELECT
CAST(P.LastName AS CHAR(50))
+ CAST(P.FirstName AS CHAR(50))
+ CAST(ISNULL(P.MiddleName,'') AS CHAR(50))
+ CAST(ea.EmailAddress AS CHAR(50))
+ CAST(a.City AS CHAR(30))
+ CAST(a.PostalCode AS CHAR(15)) AS line
INTO PersonContacts
FROM Person.Person p
INNER JOIN Person.EmailAddress ea
ON P.BusinessEntityID = ea.BusinessEntityID
INNER JOIN Person.BusinessEntityAddress bea
ON P.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address a
ON bea.AddressID = a.AddressID
Đoạn mã trên tạo thành một chuỗi dài chứa tên, địa chỉ email, thành phố và mã bưu điện. Chúng tôi cũng muốn lưu trữ nó trong Người liên hệ bảng.
Bây giờ, hãy có mã để thiết kế ngược bằng cách sử dụng SUBSTRING:
SELECT
TRIM(SUBSTRING(line,1,50)) AS [LastName]
,TRIM(SUBSTRING(line,51,50)) AS [FirstName]
,TRIM(SUBSTRING(line,101,50)) AS [MiddleName]
,TRIM(SUBSTRING(line,151,50)) AS [EmailAddress]
,TRIM(SUBSTRING(line,201,30)) AS [City]
,TRIM(SUBSTRING(line,231,15)) AS [PostalCode]
FROM PersonContacts pc
ORDER BY LastName, FirstName
Vì chúng tôi đã sử dụng các cột có kích thước cố định nên không cần sử dụng CHARINDEX.
Sử dụng SQL SUBSTRING trong mệnh đề WHERE - Bẫy hiệu suất?
Đúng rồi. Không ai có thể ngăn bạn sử dụng SUBSTRING trong mệnh đề WHERE. Nó là một cú pháp hợp lệ. Nhưng nếu nó gây ra sự cố về hiệu suất thì sao?
Đó là lý do tại sao chúng tôi chứng minh điều đó bằng một ví dụ và sau đó thảo luận cách khắc phục sự cố này. Nhưng trước tiên, hãy chuẩn bị dữ liệu của chúng tôi:
USE AdventureWorks
GO
SELECT * INTO SalesOrders FROM Sales.SalesOrderHeader soh
Tôi không thể làm rối tung SalesOrderHeader bàn, vì vậy tôi đã đổ nó sang một bàn khác. Sau đó, tôi tạo SalesOrderID trong Người bán hàng mới bảng một khóa chính.
Bây giờ, chúng tôi đã sẵn sàng cho truy vấn. Tôi đang sử dụng dbForge Studio cho SQL Server với Chế độ hồ sơ truy vấn BẬT để phân tích các truy vấn.
SELECT
so.SalesOrderID
,so.OrderDate
,so.CustomerID
,so.AccountNumber
FROM SalesOrders so
WHERE SUBSTRING(so.AccountNumber,4,4) = '4030'
Như bạn thấy, truy vấn trên chạy tốt. Bây giờ, hãy xem Sơ đồ kế hoạch hồ sơ truy vấn trong Hình 8:
Sơ đồ mặt bằng trông đơn giản, nhưng chúng ta hãy kiểm tra các thuộc tính của nút Quét chỉ mục theo cụm. Đặc biệt, chúng tôi cần Thông tin thời gian chạy:
Hình minh họa 9 cho thấy các trang 785 * 8KB được đọc bởi công cụ cơ sở dữ liệu. Cũng lưu ý rằng Số hàng thực tế là 31,411. Nó là tổng số hàng trong bảng. Tuy nhiên, truy vấn chỉ trả về 27.605 Hàng Thực tế.
Toàn bộ bảng đã được đọc bằng cách sử dụng chỉ mục nhóm làm tham chiếu.
Tại sao?
Vấn đề là, Máy chủ SQL cần biết nếu 4030 là một chuỗi con của số Tài khoản. Nó phải đọc và đánh giá từng bản ghi. Loại bỏ các hàng không bằng nhau và trả lại các hàng mà chúng ta cần. Nó hoàn thành công việc nhưng không đủ nhanh.
Chúng ta có thể làm gì để nó chạy nhanh hơn?
Tránh ĐĂNG KÝ trong Mệnh đề WHERE và Đạt được Kết quả Tương tự Nhanh hơn
Những gì chúng ta muốn bây giờ là nhận được cùng một kết quả mà không cần sử dụng SUBSTRING trong mệnh đề WHERE. Thực hiện theo các bước sau:
- Thay đổi bảng bằng cách thêm cột được tính toán với SUBSTRING (Số tài khoản, 4,4) công thức. Hãy đặt tên nó là AccountCategory vì thiếu một thuật ngữ tốt hơn.
- Tạo chỉ mục không phân cụm cho Danh mục tài khoản mới cột. Bao gồm Ngày đặt hàng , Số tài khoản và ID khách hàng cột.
Thế là xong.
Chúng tôi thay đổi mệnh đề WHERE của truy vấn để điều chỉnh Danh mục tài khoản mới cột:
SET STATISTICS IO ON
SELECT
so.SalesOrderID
,so.OrderDate
,so.CustomerID
,so.AccountNumber
FROM SalesOrders so
WHERE so.AccountCategory = '4030'
SET STATISTICS IO OFF
Không có SUBSTRING trong mệnh đề WHERE. Bây giờ, hãy kiểm tra Sơ đồ kế hoạch:
Quét chỉ mục đã được thay thế bằng Tìm kiếm chỉ mục. Cũng lưu ý rằng SQL Server đã sử dụng chỉ mục mới trên cột được tính toán. Có cả những thay đổi trong số lần đọc logic và số hàng thực tế được đọc không? Xem Hình 11:
Giảm từ 785 xuống 222 lần đọc logic là một cải tiến lớn, ít hơn ba lần so với lần đọc logic ban đầu. Nó cũng giảm thiểu các Hàng thực tế Chỉ đọc những hàng chúng ta cần.
Do đó, việc sử dụng SUBSTRING trong mệnh đề WHERE không tốt cho hiệu suất và nó sẽ áp dụng cho bất kỳ hàm có giá trị vô hướng nào khác được sử dụng trong mệnh đề WHERE.
Kết luận
- Các nhà phát triển không thể tránh việc phân tích chuỗi. Nhu cầu về nó sẽ nảy sinh theo cách này hay cách khác.
- Khi phân tích cú pháp chuỗi, điều cần thiết là phải biết thông tin trong chuỗi, vị trí của từng phần thông tin và kích thước hoặc độ dài của chúng.
- Một trong những hàm phân tích cú pháp là SQL SUBSTRING. Nó chỉ cần chuỗi để phân tích cú pháp, vị trí bắt đầu trích xuất và độ dài của chuỗi để trích xuất.
- SUBSTRING có thể có các hành vi khác nhau giữa các phiên bản SQL như SQL Server, MySQL và Oracle.
- Bạn có thể sử dụng SUBSTRING với các chuỗi ký tự và chuỗi ký tự trong các cột của bảng.
- Chúng tôi cũng đã sử dụng SUBSTRING với các ký tự Unicode.
- Sử dụng SUBSTRING hoặc bất kỳ hàm có giá trị vô hướng nào trong mệnh đề WHERE có thể làm giảm hiệu suất truy vấn. Khắc phục điều này bằng một cột được tính toán được lập chỉ mục.
Nếu bạn thấy bài đăng này hữu ích, hãy chia sẻ nó trên các nền tảng mạng xã hội ưa thích của bạn hoặc chia sẻ nhận xét của bạn bên dưới?