Dưới đây là năm tùy chọn để trả về các hàng có chứa chữ hoa trong SQL Server.
Dữ liệu mẫu
Giả sử chúng ta có một bảng với dữ liệu sau:
SELECT c1 FROM t1;
Kết quả:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
Chúng ta có thể sử dụng các phương pháp sau để trả về các hàng có chứa chữ hoa.
Tùy chọn 1:So sánh với LOWER()
Chuỗi
Chúng ta có thể sử dụng LOWER()
hàm để so sánh giá trị ban đầu với chữ thường tương đương của nó:
SELECT c1 FROM t1
WHERE LOWER(c1) COLLATE Latin1_General_CS_AS <> c1;
Kết quả:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | | É | | É 123 | | Ø | +----------------+
Bằng cách sử dụng không bằng (<>
) toán tử (bạn có thể sử dụng !=
thay vì <>
nếu bạn thích), chúng tôi chỉ trả về những hàng khác với chữ thường tương đương của chúng. Lý do chúng tôi làm điều này là bởi vì, nếu một giá trị giống với chữ thường tương đương của nó, thì nó đã là chữ thường khi bắt đầu (và chúng tôi không muốn trả lại nó).
Chúng tôi cũng sử dụng COLLATE Latin1_General_CS_AS
để chỉ định rõ ràng đối chiếu phân biệt chữ hoa chữ thường (và phân biệt trọng âm). Nếu không có điều này, bạn có thể nhận được kết quả không mong muốn, tùy thuộc vào đối chiếu đang được sử dụng trên hệ thống của bạn.
Tùy chọn 2:So sánh với các ký tự thực tế
Một tùy chọn khác là sử dụng LIKE
toán tử và chỉ định các ký tự viết hoa thực tế mà chúng tôi muốn đối sánh:
SELECT c1 FROM t1
WHERE c1 LIKE '%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%'
COLLATE Latin1_General_CS_AS;
Kết quả:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | +----------------+
Trong trường hợp này, ít hàng được trả về hơn trong ví dụ trước. Điều này là do tôi không chỉ định các ký tự như É
và Ø
, được trả về trong ví dụ trước. Kết quả của chúng tôi có chứa É
nhưng hàng đó chỉ được trả về vì nó cũng chứa các ký tự viết hoa khác do phù hợp.
Do đó, tùy chọn này bị hạn chế hơn tùy chọn trước đó, nhưng nó cung cấp cho bạn nhiều quyền kiểm soát hơn đối với các ký tự bạn muốn khớp.
Tùy chọn 3:So sánh với một loạt các ký tự
Ngoài ra, chúng tôi có thể chỉ định phạm vi ký tự mà chúng tôi muốn đối sánh:
SELECT * FROM t1
WHERE c1 LIKE '%[A-Z]%'
COLLATE Latin1_General_100_BIN2;
Kết quả:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | +----------------+
Trong trường hợp này, tôi đã sử dụng đối chiếu nhị phân (Latin1_General_100_BIN2
). Tôi đã làm điều này vì đối chiếu nhị phân sắp xếp từng trường hợp riêng biệt (như thế này:AB....YZ...ab...yz
).
Các ảnh ghép khác có xu hướng xen kẽ chữ hoa và chữ thường (như thế này:AaBb...YyZz
), do đó sẽ khớp với cả ký tự viết hoa và viết thường.
Tùy chọn 4:Tìm Bản sao đầu tiên của một ký tự viết hoa
Một cách khác để làm điều đó là sử dụng PATINDEX()
chức năng:
SELECT * FROM t1
WHERE PATINDEX('%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Kết quả:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | eCafé | | James Bond 007 | | JB 007 | +----------------+
Trong ví dụ này, chúng tôi chỉ định các ký tự chính xác mà chúng tôi muốn đối sánh và do đó, trong trường hợp này, chúng tôi không nhận được các hàng có các ký tự như É
và Ø
(ngoại trừ cái cũng chứa các ký tự khác đã khớp).
Một lợi ích của kỹ thuật này là chúng tôi có thể sử dụng nó để bỏ qua ký tự đầu tiên (hoặc số ký tự được chỉ định) nếu chúng tôi muốn:
SELECT * FROM t1
WHERE PATINDEX('%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Kết quả:
Time: 0.472s +-------+ | c1 | |-------| | eCafé | +-------+
Do đó, chúng ta có thể trả về tất cả các hàng có chứa ký tự viết hoa, nhưng ký tự đầu tiên không phải là ký tự viết hoa.
Điều này là do PATINDEX()
trả về vị trí bắt đầu của lần xuất hiện đầu tiên của mẫu (trong trường hợp của chúng ta, mẫu là danh sách các ký tự viết hoa). Nếu vị trí bắt đầu của lần xuất hiện đầu tiên lớn hơn 1, thì ký tự đầu tiên không có trong danh sách các ký tự viết hoa của chúng tôi.
Tùy chọn 5:Tìm phiên bản đầu tiên dựa trên phạm vi
Chúng tôi cũng có thể sử dụng PATINDEX()
với một phạm vi:
SELECT * FROM t1
WHERE PATINDEX('%[A-Z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Kết quả:
+-------+ | c1 | |-------| | eCafé | +-------+
Tôi lại sử dụng đối chiếu nhị phân (giống như với ví dụ về phạm vi khác).