สตริงแบบสอบถาม MySQL มี


307

ฉันพยายามหาวิธีที่ฉันสามารถสร้างแบบสอบถามด้วย MySQL ที่ตรวจสอบว่าค่า (สตริง$haystack) ในคอลัมน์หนึ่งมีข้อมูลบางอย่าง (สตริง$needle) เช่นนี้หรือไม่:

mysql_query("
SELECT *
FROM `table`
WHERE `column`.contains('{$needle}')
");

ใน PHP เรียกใช้ฟังก์ชันsubstr($haystack, $needle)ดังนั้นอาจจะ:

WHERE substr(`column`, '{$needle}')=1

คำตอบ:


437

ค่อนข้างง่ายจริง ๆ :

mysql_query("
SELECT *
FROM `table`
WHERE `column` LIKE '%{$needle}%'
");

%เป็นสัญลักษณ์แทนตัวอักษรใด ๆ ที่ตั้ง (ไม่มีอย่างใดอย่างหนึ่งหรือหลายบริการ) โปรดทราบว่าการทำเช่นนี้อาจทำให้ชุดข้อมูลขนาดใหญ่ช้าลงดังนั้นหากฐานข้อมูลของคุณเติบโตขึ้นคุณจะต้องใช้ดัชนีแบบเต็ม


1
วิธีนี้จะใช้งานได้หากคุณใช้ข้อความค้นหาที่เตรียมไว้ หากคุณกำลังใช้สตริงจริงอยู่ในนั้น (เช่นสคริปต์อัพเกรด liquibase sql) ให้พิจารณา INSTR ที่ระบุด้านล่าง) นี่เป็นเพราะหากสตริงของคุณมี% คุณจะเริ่มจับคู่สิ่งนั้นกับมัน
Ryan Shillington

2
ฉันรู้ว่าชอบข้อความค้นหา แต่วันนี้ฉันต้องการทราบว่ามีค่าบางอย่างอยู่ในสตริงในคอลัมน์ที่ฉันไปหรือเปล่า .. ทำไมฉันไม่เคยคิดถึงมันมาก่อน?
รหัสร้อน

1
กรณีนี้ละเอียดอ่อนหรือไม่
กีวีโกรธ

2
@angry_kiwi: ด้วยcolumn LIKE '...'ตัวพิมพ์เล็กและตัวพิมพ์column LIKE BINARY '...'เล็ก
Wolph

2
ฉันประหลาดใจที่LIKEจะเสนอให้ตรวจสอบการย่อยใด ๆ ตั้งแต่ดำเนินการนี้ใช้สองอักขระตัวแทน: และ% _ซึ่งหมายความว่าถ้าสตริงเข็ม $ ของคุณมีอักขระพิเศษตัวใดตัวหนึ่งผลลัพธ์จะไม่เป็นไปตามที่คาดไว้ (-1) สำหรับคำตอบนี้และ (+1) สำหรับคำตอบ INSTR
Skrol29

144

ใช้:

SELECT *
  FROM `table`
 WHERE INSTR(`column`, '{$needle}') > 0

อ้างอิง:


แน่นอน LIKE เร็วกว่า INSTR หรือไม่
chris

17
@oedo: ขึ้นอยู่กับ LIKE %...%จะไม่ใช้ดัชนีหากมีอยู่ดังนั้นพวกเขาควรจะเทียบเท่า; LIKE ...%จะใช้ดัชนีถ้ามี หากประสิทธิภาพเป็นเรื่องจริงการค้นหาข้อความแบบเต็ม (FTS) จะเป็นวิธีที่ดีกว่า
OMG Ponies

สมบูรณ์ สิ่งที่ฉันกำลังมองหา
arik

2
ฉันชอบวิธีนี้เพราะในความเป็นจริงไม่มีวิธีการเรียงลำดับสิ่งต่าง ๆ ตามสถานะของสตริงย่อยที่มีlikeตัวดำเนินการ ด้วยinstrวลีที่สามารถสั่งซื้อได้เช่นนี้select * from table order by instr(col1,"mystring")
Radacina

ฉันต้องการค้นหา _ ในฟิลด์และทำงานได้ ขอบคุณ
Safeer Ahmed

53
WHERE `column` LIKE '%$needle%'

2
เมื่อค้นหาอักขระ _ (ขีดล่าง) เคียวรี LIKE '% _%' ไม่ทำงานด้วยเหตุผลบางอย่างมันจะส่งคืนสตริงทั้งหมดแม้ไม่มี _
Wojtek

1
@Wojtek _ เป็นอักขระตัวแทนสำหรับอักขระเดี่ยวใด ๆ ดังนั้นหากคุณต้องการค้นหาเครื่องหมายขีดล่างที่แท้จริงคุณจะต้องหลีกเลี่ยง ดูMySQL แบบสอบถามเช่นเดียวกับขีด
jkmartindale

29

ฉันใช้LOCATEใน mysql:

LOCATE (substr, str), LOCATE (substr, str, pos)

ฟังก์ชั่นนี้ปลอดภัยแบบหลายไบต์และคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่หากอาร์กิวเมนต์อย่างน้อยหนึ่งรายการเป็นสตริงไบนารี

ในกรณีของคุณ:

mysql_query("
SELECT * FROM `table`
WHERE LOCATE('{$needle}','column') > 0
");

11
'column' ควรเป็น column (ไม่มีเครื่องหมายคำพูด)
Wojtek

10

นอกจากคำตอบจาก @WoLpH

เมื่อใช้LIKEคำหลักคุณจะสามารถ จำกัด ทิศทางของสตริงได้ ตัวอย่างเช่น:

หากคุณกำลังมองหาสตริงที่ขึ้นต้นด้วย$needle:

... WHERE column LIKE '{$needle}%'

หากคุณกำลังมองหาสตริงที่ลงท้ายด้วย$needle:

... WHERE column LIKE '%{$needle}'

3

ระวังว่านี่เป็นอันตราย:

WHERE `column` LIKE '%{$needle}%'

ทำก่อน:

$needle = mysql_real_escape_string($needle);

ดังนั้นมันจะป้องกันการโจมตีที่เป็นไปได้


7
* การโจมตีที่เป็นไปได้บางอย่าง และmysql_real_escape_stringจะมีการเลิกใช้ในรุ่น PHP ในอนาคต
Jack Tuck

11
คุณควรใช้คำสั่งที่เตรียมไว้และปล่อยให้หนีไปยัง PHP $stmt = $dbh->prepare("Where 'column' LIKE '{:needle}'"); $stmt->bindParam(':needle', $needle); $stmt->execute();
cloudworks

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.