2010-09-16 21 views
5

Im utilizzando il seguente PHP e MySQL per recuperare righe da una tabella,PHP/MySQL Ricerca - Case sensitive

$search_word=$_GET['search_word']; 
$search_word_new=mysql_escape_string($search_word); 
$search_word_fix=str_replace(" ","%",$search_word_new); 
$sql=mysql_query("SELECT * FROM tweets WHERE content LIKE '%$search_word_fix%' ORDER BY votes DESC LIMIT 20"); 

Il campo 'contenuto' è un campo di testo che contiene i tweet.

Il problema che ho è se cerco 'S tackoverflow' ottengo tutti i risultati che contengono 'StackOverflow' ma i risultati non quando il testo è 's tackoverflow'. Fondamentalmente la ricerca è case sensitive.

È possibile modificare la query o PHP, pertanto quando si cerca "StackOverflow" vengono restituiti sia i risultati maiuscoli che minuscoli?

risposta

4

si può provare:

$search_word_fix=strtolower(str_replace(" ","%",$search_word_new)); 
$sql=mysql_query("SELECT * FROM tweets WHERE lower(content) LIKE '%$search_word_fix%' ORDER BY votes DESC LIMIT 20"); 
  • Ho aggiunto strtolower per rendere $search_word_fix in lettere minuscole.
  • E nella clausola where ho cambiato content a lower(content) in modo che paragono con minuscola di content.

Si potrebbe aver fatto entrambe le modifiche nella query come suggerito in un'altra risposta.

+0

La soluzione più semplice per me come novizio di PHP. – CLiown

+1

Più semplice! = Meglio. Questo non trarrà alcun vantaggio da alcun indice possibile, ed è molto probabilmente più lento. (disse l'idiota pomposo che in realtà era solo rattristato dal fatto che a nessuno sembra importare la collazione insensibile alle maiuscole in MySQL). – Wrikken

3

forzare il caso sia del termine di ricerca e il valore della colonna:

SELECT * FROM tweets WHERE LOWER(content) LIKE LOWER('%$search_word_fix%') ORDER BY votes DESC LIMIT 20 

o:

SELECT * FROM tweets WHERE UPPER(content) LIKE UPPER('%$search_word_fix%') ORDER BY votes DESC LIMIT 20 

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

3

Il modo 'corretto' per farlo è quello di impostarlo su case-insensitive collazione:

CREATE TABLE foo (col1 varchar(24) COLLATE utf8_bin,col2 varchar(24) COLLATE utf8_general_ci); 
Query OK, 0 rows affected (0.03 sec) 

DB 5.1.49-1-log:test mysql> INSERT INTO foo VALUES ('stackoverflow','stackoverflow'); 
Query OK, 1 row affected (0.01 sec) 

DB 5.1.49-1-log:test mysql> SELECT * FROM foo WHERE col1 LIKE 'Stackoverflow'; 
Empty set (0.00 sec) 

DB 5.1.49-1-log:test mysql> SELECT * FROM foo WHERE col2 LIKE 'Stackoverflow'; 
+---------------+---------------+ 
| col1   | col2   | 
+---------------+---------------+ 
| stackoverflow | stackoverflow | 
+---------------+---------------+ 
1 row in set (0.00 sec) 

DB 5.1.49-1-log:test mysql> SELECT * FROM foo WHERE col1 COLLATE utf8_general_ci LIKE 'Stackoverflow'; 
+---------------+---------------+ 
| col1   | col2   | 
+---------------+---------------+ 
| stackoverflow | stackoverflow | 
+---------------+---------------+ 
1 row in set (0.00 sec) 
+1

Non utilizzare la clausola 'COLLATE' a meno che non sia semplicemente possibile modificare le regole di confronto della colonna: non è possibile utilizzare l'indice. –

0

mysql> SELECT * FROM myDb.myTable dove username = 'test980'; 1 riga nel set (0,00 secondi)

mysql> SELECT * FROM myDb.myTable WHERE username = 'TEST980'; Set vuoto (0,00 secondi)

Le colonne MySQL possono essere rese case sensitive creando le parole chiave binarie. Sospetto che questo sia il tuo problema. È possibile modificare la colonna in modo che non sia binario o modificare la query in:

SELECT * FROM myDb.myTable WHERE UCASE (username) = 'TEST980';

che rende efficace il confronto tra stringhe senza distinzione tra maiuscole e minuscole nonostante il set di caratteri binari scelto.

+0

'BINARY' e' UCASE' sono costosi perché l'indice non può essere utilizzato. –

0

Si tratta di scegliere le migliori regole di confronto durante la creazione del database MySql.

  • utf8_unicode_ci è utile se si desidera ordinare per esempio il set di caratteri tedesco con precisione, ma è lento.
  • utf8_general_ci è lo standard predefinito quando si crea il set di caratteri del database MySQL utf8 ed è il più veloce, ma senza distinzione tra maiuscole e minuscole.
  • Regola del pollice: usa sempre utf8_general_ci su MySQL e collaziona utf8_bin se necessario per la distinzione tra maiuscole e minuscole OPPURE usa SELECT BINARY nella tua istruzione.
1

Modificare il COLLATION della colonna in questione (content) per essere case insensitive, come ad esempio utf8mb4_unicode_ci.

Fare il caso di piegare in PHP è costoso e inefficiente.

Problemi correlati