2010-05-20 4 views
10

un'occhiata a questa tabella si prega diselezionare ... dove id = qualsiasi valore. È possibile?

table 
|id| |name| |order| 

devo ottenere le righe, dove name = something e order = somevalue

Così scrivo

select `id` from `table` where `name` = 'something' and `order` = 'somevalue' 

ma dipendono logica php, a volte ho bisogno di ottenere tutti righe, dove name = something, indipendentemente dal valore order. non voglio cambiare la struttura della query, perché in pratica ci sono molti campi e il numero possibile di query diventerà molto grande. così voglio Salva la struttura di query e quando ho bisogno di selezionare solo per nome, voglio scrivere qualcosa del genere:

select `id` from `table` where `name` = 'something' and `order` = any value 

è possibile?

grazie

+1

vorrei cambiare il modo in cui si sta costruendo le vostre domande ... – nickf

risposta

10

bene, è una specie di hack, ma se si ha realmente bisogno di fare questo, funzionerà in questo modo:

select `id` from `table` where `name` = 'something' and `order` = `order` 

Poi si sta solo dicendo "dovunque ordine è lo stesso di se stesso ", quindi è sempre vero.

+2

vorrei prendere in considerazione questa modifica della struttura, in quanto la sintassi per riferirsi a un campo non è la stessa di quella per riferirsi a una stringa. –

+0

Questo non è il modo corretto di farlo. Il codice php deve essere regolato. – vonPetrushev

5

No, questo non è possibile. Hai bisogno di cambiare la struttura (opzionalmente in un LIKE così puoi usare '%', ma è molto brutto).

Tuttavia, non è necessario scrivere una query diversa per gestire tutte le combinazioni possibili. Si può semplicemente creare la query in modo dinamico:

//create base query 
$query = "select `id` from `table` where `name` = 'something' "; 

//add order if we need it 
if ($use_order) 
    $query .= "and `order` = 'somevalue' "; 

//repeat for any other optional part 

Nota che si deve naturalmente ancora prendere le misure adeguate per evitare l'iniezione SQL e altre questioni di sicurezza - non ho incluso in questa sede, al fine di mantenere le cose semplici.

+0

cos'è l'iniezione SQL? forse parli di mysql_real_escape_string() e di tali funzioni? Non capisco il significato di "SQL injection" – Simon

+0

@Syom: SQL injection è l'atto di fornire dati che influenzano la struttura della query, causando di fare qualcosa di diverso da quello che avrebbe dovuto fare. mysql (i) _real_escape_string è in effetti ciò che la maggior parte delle persone usa per impedirlo (sebbene le query parametrizzate siano strettamente un approccio migliore, ma questo è un argomento diverso). Se vuoi saperne di più, ci sono molte buone risorse, sia su SO che su Google. Tutto quello che sto cercando di dire è che devi ancora ricordare di fare questo genere di cose quando costruisci dinamicamente. –

2

Se si utilizzano parametri associati, sarebbe impossibile.

Se basta sostituire i valori, è possibile effettuare le seguenti operazioni:

select `id` from `table` where `name` = 'something' and `order` = `order` 
0

io non pensi di avere alcuna scelta ... Una volta che fate una selezione non si può "unfilter" e ottenere più file.

È necessario utilizzare due query: due query indipendenti o una che seleziona il nome in una tabella temporanea e quindi (facoltativamente) una che seleziona ulteriormente sull'attributo dell'ordine.

0

Come ha detto sopra Chad, basta impostare la colonna uguale a se stessa. Ma attenzione, su alcune piattaforme/installare configurazioni, NULL = NULL:

select `id` from `table` where `name` = 'something' and coalesce(`order`,'') = coalesce(`order`,'') 
+4

NULL! = NULL è in realtà il comportamento previsto, come definito nello standard SQL. –

0

Questo è un tema comune con le query di database - è necessario una query variabile a seconda di quanto il filtro che si desidera applicare ai dati esso! interrogazioni. È possibile seguire il percorso di ripetizione della query come stringa nel codice, ma questa è una cattiva pratica in quanto aumenta inutilmente la complessità del codice. Le probabilità di errori si verificano se è necessario modificare la query per qualche motivo e, di conseguenza, è necessario modificarla in più punti.

La soluzione migliore è quella di creare una funzione che costruisce la query per eseguire:

function buildMyQuery($name, $order = null) { 
    $sql = "SELECT `id` FROM `table` WHERE `name`='$name'"; 

    if ($order != null) { 
     $sql .= " AND `order`='$order'"; 
    } 

    return $sql; 
} 

È quindi possibile eseguire questo solo utilizzando il campo 'Nome':

$query = buildMyQuery("somename"); 

O questo per l'utilizzo di entrambi i campi:

$query = buildMyQuery("somename", "someorder"); 

Come qualcuno di cui sopra, questo codice è volutamente semplice lified e non contiene alcuna eventualità per dati potenzialmente pericolosi trasmessi tramite $ name o $ order. Dovresti utilizzare mysql_real_escape_string o qualcosa di simile per pulire prima i dati, all'inizio della funzione, prima che venga utilizzato uno dei due dati.

La generazione di query dinamiche è un dato di fatto, come dice Byron, quindi mi ci abituerei ora piuttosto che usare soluzioni alternative.

0

Riflettendo, ho una risposta migliore. Il mio collega mi ha mostrato un modo in cui questo può essere fatto.

Il mio esempio ...

Select rentals.* From rentals Where ((? = '') OR (user_id = ?)) 

Le variabili devono essere gli stessi.

Se sono entrambi 5 per esempio, il primo booleano sarà falso, ma la seconda sarà vero, per le righe in cui gli utenti id è 5.

Se avete bisogno di "tutti", impostando come una stringa vuota comporterà la visualizzazione di tutte le righe per soddisfare la condizione della clausola where.

0

Non puoi semplicemente utilizzare una query not null qui?

select `id` from `table` where `name` = 'something' and `order` is not null;