ฉันต้องการเลือกระเบียนจากฐานข้อมูล sqlite3 โดยการจับคู่สตริง แต่ถ้าฉันใช้ '=' ในส่วนคำสั่ง where ฉันพบว่า sqlite3 เป็นแบบตรงตัวพิมพ์ มีใครบอกวิธีใช้สตริงเปรียบเทียบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ได้ไหม
ฉันต้องการเลือกระเบียนจากฐานข้อมูล sqlite3 โดยการจับคู่สตริง แต่ถ้าฉันใช้ '=' ในส่วนคำสั่ง where ฉันพบว่า sqlite3 เป็นแบบตรงตัวพิมพ์ มีใครบอกวิธีใช้สตริงเปรียบเทียบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ได้ไหม
คำตอบ:
คุณสามารถใช้COLLATE NOCASE
ในการSELECT
สอบถามของคุณ:
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
นอกจากนี้ใน SQLite คุณสามารถระบุได้ว่าคอลัมน์ควรคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่เมื่อคุณสร้างตารางโดยการระบุcollate nocase
ในการกำหนดคอลัมน์ (ตัวเลือกอื่นคือbinary
(ค่าเริ่มต้น) และrtrim
; ดูที่นี่ ) คุณสามารถระบุcollate nocase
เมื่อคุณสร้างดัชนีได้เช่นกัน ตัวอย่างเช่น:
สร้างตารางทดสอบ ( Text_Value ตรวจสอบข้อความ nocase ); แทรกลงในค่าทดสอบ ('A'); แทรกลงในค่าทดสอบ ('b'); แทรกลงในค่าทดสอบ ('C'); สร้างดัชนี Test_Text_Value_Index เมื่อทดสอบ (Text_Value collate nocase);
นิพจน์ที่เกี่ยวข้องTest.Text_Value
ควรเป็นแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ ตัวอย่างเช่น:
sqlite> เลือก Text_Value จาก Test โดยที่ Text_Value = 'B'; TEXT_VALUE ---------------- ข sqlite> เลือก Text_Value จากคำสั่งทดสอบโดย Text_Value; TEXT_VALUE ---------------- ข ค sqlite> เลือก Text_Value จากคำสั่งทดสอบโดย Text_Value desc; TEXT_VALUE ---------------- ค ข
เครื่องมือเพิ่มประสิทธิภาพอาจใช้ประโยชน์จากดัชนีสำหรับการค้นหาและการจับคู่ตามตัวพิมพ์เล็กและใหญ่ในคอลัมน์ คุณสามารถตรวจสอบสิ่งนี้ได้โดยใช้explain
คำสั่ง SQL เช่น:
sqlite> อธิบายเลือก Text_Value จาก Test โดยที่ Text_Value = 'b'; addr opcode p1 p2 p3 ---------------- -------------- ---------- ---------- --------------------------------- 0 ไปที่ 0 16 1 จำนวนเต็ม 0 0 2 OpenRead 1 3 keyinfo (1, NOCASE) 3 SetNumColumns 1 2 4 String8 0 0 b 5 IsNull -1 14 6 MakeRecord 1 0 a 7 MemStore 0 0 8 MoveGe 1 14 9 MemLoad 0 0 10 IdxGE 1 14 + 11 คอลัมน์ 1 0 12 การโทรกลับ 1 0 13 ถัดไป 1 9 14 ปิด 1 0 15 หยุด 0 0 16 รายการ 0 0 17 VerifyCookie 0 4 18 ไปที่ 0 1 19 นพ 0 0
COLLATE NOCASE
ลงในดัชนีไม่จำเป็นถ้าฟิลด์นั้นมีการเรียงลำดับที่กำหนดไว้แล้ว: " ลำดับการเรียงเริ่มต้นคือลำดับการเรียงที่กำหนดไว้สำหรับคอลัมน์นั้นในคำสั่ง CREATE TABLE "
COLLATE NOCASE
จะทำงานกับข้อความ ASCII เท่านั้น เมื่อคุณมี "FIANCÉ" หรือ "voilà" ในค่าคอลัมน์ของคุณแล้วจะไม่ตรงกับ "fiancé" หรือ "VOILA" หลังจากเปิดใช้งานส่วนขยาย ICU LIKE
จะกลายเป็นตัวพิมพ์เล็กและตัวพิมพ์เล็กดังนั้นจึง'FIANCÉ' LIKE 'fiancé'
เป็นความจริง แต่'VOILA' LIKE 'voilà'
ก็ยังเป็นเท็จ และ ICU + LIKE มีข้อเสียเปรียบในการไม่ใช้ดัชนีดังนั้นมันอาจช้าในตารางขนาดใหญ่
select * from tbl where firstname='john' and lastname='doe' COLLATE NOCASE
จะเป็นตัวพิมพ์เล็กและตัวพิมพ์lastname
เล็ก จะเป็นกรณีตายบนเขียนนี้:firstname
select * from tbl where firstname='john' COLLATE NOCASE and lastname='doe'
มันเฉพาะเจาะจงกับหนึ่งคอลัมน์นั้นไม่ใช่ทั้งwhere
ประโยค
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
คุณสามารถทำได้เช่นนี้:
SELECT * FROM ... WHERE name LIKE 'someone'
(มันไม่ได้วิธีการแก้ปัญหา แต่ในบางกรณีมีความสะดวกมาก)
"ตัวดำเนินการLIKEทำการเปรียบเทียบรูปแบบที่ตรงกันตัวถูกดำเนินการทางด้านขวามีรูปแบบตัวถูกดำเนินการทางซ้ายมีสตริงที่ตรงกับรูปแบบสัญลักษณ์เปอร์เซ็นต์ ("% ") ในรูปแบบตรงกับลำดับใด ๆ ของศูนย์หรือมากกว่า อักขระในสตริงเครื่องหมายขีดล่าง ("_") ในรูปแบบตรงกับอักขระเดี่ยวใด ๆ ในสตริงอักขระอื่นใดตรงกับ ตัวเองหรือ เทียบเท่า กับตัวพิมพ์เล็ก / ใหญ่(เช่นการจับคู่ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) (ข้อผิดพลาด: SQLite เข้าใจเท่านั้น ตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็กสำหรับอักขระ ASCII ตัวดำเนินการ LIKE คำนึงถึงตัวอักษรพิมพ์เล็กสำหรับอักขระ unicode ที่อยู่นอกช่วง ASCII ตัวอย่างเช่นนิพจน์ 'a' LIKE 'A' เป็น TRUE แต่ 'æ' LIKE 'Æ'คือ FALSE)
นี่ไม่ใช่เฉพาะ sqlite แต่คุณสามารถทำได้
SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')
ตัวเลือกอื่นคือการสร้างการเรียงหน้าแบบกำหนดเองของคุณเอง จากนั้นคุณสามารถตั้งค่าการเรียงในคอลัมน์หรือเพิ่มลงในส่วนคำสั่งที่คุณเลือก มันจะถูกใช้สำหรับการสั่งซื้อและการเปรียบเทียบ
สามารถใช้เพื่อสร้าง 'VOILA' LIKE 'voilà'
http://www.sqlite.org/capi3ref.html#sqlite3_create_collation
ฟังก์ชันการเรียงจะต้องส่งคืนจำนวนเต็มที่เป็นค่าลบศูนย์หรือบวกหากสตริงแรกน้อยกว่าเท่ากับหรือมากกว่าที่สองตามลำดับ
ตัวเลือกอื่นที่อาจหรืออาจไม่สมเหตุสมผลในกรณีของคุณคือการมีคอลัมน์แยกต่างหากที่มีค่าต่ำกว่าที่เก็บไว้ในคอลัมน์ที่คุณมีอยู่ สิ่งนี้สามารถบรรจุโดยใช้ฟังก์ชัน SQLite LOWER()
และจากนั้นคุณสามารถทำการจับคู่ในคอลัมน์นี้แทน
เห็นได้ชัดว่ามันเพิ่มความซ้ำซ้อนและศักยภาพในการไม่สอดคล้องกัน แต่ถ้าข้อมูลของคุณเป็นแบบคงที่อาจเป็นตัวเลือกที่เหมาะสม
เพียงแค่คุณสามารถใช้ COLLATE NOCASE ในคิวรี SELECT ของคุณ:
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
คุณสามารถใช้คิวรี่ที่คล้ายกันเพื่อเปรียบเทียบสตริงที่เกี่ยวข้องกับวาลตาราง
เลือกชื่อคอลัมน์จาก table_name โดยที่ชื่อคอลัมน์เช่น 'การเปรียบเทียบตามลำดับ';
มันทำงานให้ฉันอย่างสมบูรณ์แบบ
SELECT NAME FROM TABLE_NAME WHERE NAME = 'test Name' COLLATE NOCASE