2009-10-21 6 views
0

J'essaie de comprendre comment obtenir une instruction select à remplir par un nombre en constante évolution de where. Ceci est pour une application de suivi de l'état des commandes. Fondamentalement, l'idée est qu'un utilisateur (client de notre société) se connecte, et peut voir ses commandes, vérifier son statut, etc. Pas de problème. Le problème se pose lorsque cet utilisateur doit être associé à plusieurs sociétés. Supposons qu'ils travaillent ou possèdent deux sociétés différentes, ou qu'ils travaillent pour une société qui possède plusieurs sous-sociétés, chaque commande individuellement, mais le big-shot doit voir tout commandé par toutes les entreprises. C'est là que je rencontre un problème. Je n'arrive pas à trouver un bon moyen d'y arriver. La seule chose que je suis venu avec ceci:
PHP/MYSQL: instruction SELECT, plusieurs où, rempli à partir de la base de données


client='Client Name One' OR client='Client name two' AND hidden='0' OR client='Client name three' AND hidden='0' OR client='Client name four' AND hidden='0' 

(Notez que le client dans le code précédent fait référence à la société de l'utilisateur, ainsi notre client)

placé à l'intérieur d'une colonne appelée entreprise ma table d'utilisateurs de la base de données. Cela s'appelait alors comme ceci:


$clientnamequery = "SELECT company FROM mtc_users WHERE username='testing'"; 
$clientnameresult = mysql_query($clientnamequery); list($clientname)=mysql_fetch_row($clientnameresult); 

$query = "SELECT -redacted lots of column names- FROM info WHERE hidden='0' AND $clientname ORDER BY $col $dir"; 
$result = mysql_query($query); 

Chose est, alors que cela fonctionne, je ne peux pas sembler faire PHP ajouter dans le client = » et « ET cachés = » 0' correctement. De plus, c'est un peu kludgy.

Des idées? Merci d'avance!

+0

Dans ce cas, la réduction à une instruction SQL unique est la voie à suivre. Dans d'autres cas, vous pouvez utiliser 'implode' pour générer une chaîne à partir d'une séquence:' "(client = '". Implode ("' OR client = '", exploser (', ', $ clientsnames)).' ') AND hidden = 0 "' – outis

Répondre

1

L'expansion sur la réponse de Tim, vous pouvez utiliser le IN operator et subqueries:

SELECT *columns* FROM info 
    WHERE hidden='0' AND client IN 
    ( SELECT company FROM co_members 
     WHERE username=? 
) 
    ORDER BY ... 

Ou vous pouvez essayer un join:

SELECT info.* FROM info 
    JOIN co_members ON info.client = co_members.company 
    WHERE co_members.username=? 
    AND hidden='0' 
    ORDER BY ... 

Une jointure est l'approche préférée. Entre autres raisons, il sera probablement le plus efficace (bien que vous devriez tester cela avec EXPLAIN SELECT ...). Vous ne devriez probablement pas récupérer toutes les colonnes de la table (info.*) au cas où vous pourriez changer la définition de la table plus tard; Je n'ai mis que ça parce que je ne savais pas quelles colonnes vous vouliez.

Sur une note non liée, examinez en utilisant des requêtes préparées avec les pilotes mysqli ou PDO. Les requêtes préparées sont plus efficaces lorsque vous exécutez une requête plusieurs fois et évitez également d'avoir à nettoyer les entrées utilisateur.

L'approche relationnelle implique des tables comme:

CREATE TABLE mtc_users (
    username PRIMARY KEY, 
    -- ... other user info 
) ENGINE=InnoDB; 

CREATE TABLE companies (
    id INT PRIMARY KEY AUTO_INCREMENT, 
    name VARCHAR() NOT NULL, 
    -- ... other company info 
) ENGINE=InnoDB; 

CREATE TABLE co_members (
    username NOT NULL, 
    company NOT NULL, 
    FOREIGN KEY (`username`) REFERENCES mtc_users (`username`) 
     ON DELETE CASCADE 
     ON UPDATE CASCADE, 
    FOREIGN KEY (`company`) REFERENCES companies (`id`) 
     ON DELETE CASCADE 
     ON UPDATE CASCADE, 
    INDEX (`username`, `company`) 
) ENGINE=InnoDB; 

Si les noms de l'entreprise doivent être uniques, vous pourriez les utiliser comme une clé primaire plutôt qu'un champ id. "co_members" est un mauvais nom, mais "employés" et "actionnaires" ne semblent pas tout à fait les termes corrects. Comme vous êtes plus familier avec le système, vous serez en mesure de trouver un nom plus approprié.

+0

Comment les sociétés de la colonne company devraient-elles être disposées (dans mtc_users) dans la base de données pour fonctionner? –

+0

La table doit contenir la relation d'entreprise <->, avec une ligne pour chaque société dont un utilisateur fait partie. Si mtc_users contient les propriétés des utilisateurs (1 ligne pour chaque utilisateur), créez une nouvelle table et utilisez-la à la place. – outis

+0

outis, vous êtes génial. –

0

Vous pouvez utiliser le mot-clé IN

client IN('client1','client2',...) 
+0

Cela ne semble pas fonctionner.Il est à noter que la colonne avec laquelle elle compare ne contient que le nom d'un client (dans le tableau des ordres). Donc, l'idée est qu'il montre à cet utilisateur toutes les commandes du client un et le client deux et le client trois et ainsi de suite. Cependant, je n'ai pas trouvé de page mysql parlant d'IN, mais c'est un mot très populaire ... –

+0

Doc pour l'opérateur IN: http://dev.mysql.com/doc/refman/5.0/fr/ comparison-operators.html # function_in – outis

Questions connexes