2010-03-12 5 views
2

J'ai créé un formulaire en PHP qui recueille des informations de base. J'ai une zone de liste qui permet de sélectionner plusieurs éléments (logement, location, nourriture, eau). Si plusieurs éléments sont sélectionnés, ils sont stockés dans un champ appelé Besoins séparés par une virgule. J'ai créé un rapport commandé par les besoins des personnes. Les personnes qui n'ont qu'un besoin sont triées correctement, mais les personnes qui en ont plusieurs sont triées exactement comme la chaîne passée à la base de données (logement, location, nourriture, eau) -> ce qui n'est pas ce que je veux.Récupérer des données délimitées par des virgules d'un champ

Existe-t-il un moyen de séparer les valeurs multiples dans ce champ en utilisant SQL pour compter chaque instance/occurrence de besoin en tant que 1 afin qu'il n'y ait aucune délimitation de virgule montrée dans les résultats?

+5

C'est une mauvaise conception de base de données. Vous ne devez pas créer de champs SQL ayant une structure interne. –

+0

Oui, c'est un mauvais design mais il est possible d'obtenir le résultat désiré. Quel DB utilisez-vous? Ajoutez les tags appropriés pour attirer l'attention des spécialistes de votre base de données. Certains DB ont un SQL récursif et/ou ont des fonctions spéciales. – redcayuga

Répondre

0

Je suis un peu confus par l'objectif. Est-ce un problème d'assurance-chômage ou avez-vous de la difficulté à déterminer qui a de multiples besoins?

Le nombre de besoins est la différence:

Len([Needs]) - Len(Replace([Needs],',','')) + 1 

Pouvez-vous fournir plus d'informations sur le type que vous essayez d'accomplir?

MISE À JOUR: Je pense que ces postes basés sur Oracle peuvent avoir ce que vous cherchez: post et post. La seule différence est que vous feriez mieux d'utiliser la méthode que je liste ci-dessus pour trouver le nombre de morceaux délimités par des virgules plutôt que de faire le translate (...) que l'auteur suggère. J'espère que cela aide - c'est basé sur Oracle, mais je ne vois pas.

+0

Pour être un peu plus clair, les tableaux listés ne sont que des exemples et ne sont en aucun cas des champs réels dans la base de données. J'ai été chargé de créer une base de données simple qui capture les informations de base des consommateurs et leurs besoins pour une organisation. Le problème est que, une fois les tests terminés et les premières personnes entrées dans la base de données, les responsables ont demandé que des champs et des informations supplémentaires soient capturés. Mes requêtes fonctionnent bien, je ne sais pas comment traiter chaque variable dans la colonne des besoins en tant qu'individu en utilisant SQL. J'espère que cela pourra aider. – Nichols

+0

Vous allez avoir beaucoup de problèmes avec cette colonne délimitée dans une requête, sauf si vous le convertissez d'abord en une table temporaire ou une variable de table en premier - SQL n'a pas vraiment de bonnes fonctionnalités de type .Split (...) . Il existe de très bons exemples de comment analyser les colonnes de valeurs séparées par des virgules: http://www.sqlbook.com/SQL/Parse-a-comma-delimited-list-8.aspx – fordareh

2

Votre base de données n'est pas dans le département first normal form. Une base de données non normalisée sera très problématique à utiliser et à interroger, comme vous le faites actuellement.

En général, vous devriez utiliser au moins la structure suivante. Il peut encore être normalisée plus loin, mais j'espère que cela vous arrive d'aller dans la bonne direction:

CREATE TABLE users (
    user_id int, 
    name varchar(100) 
); 

CREATE TABLE users_needs (
    need  varchar(100), 
    user_id int 
); 

Ensuite, vous devez stocker les données comme suit:

-- TABLE: users 

+---------+-------+ 
| user_id | name | 
+---------+-------+ 
|  1 | joe | 
|  2 | peter | 
|  3 | steve | 
|  4 | clint | 
+---------+-------+ 

-- TABLE: users_needs 

+---------+----------+ 
| need | user_id | 
+---------+----------+ 
| housing |  1 | 
| water |  1 | 
| food |  1 | 
| housing |  2 | 
| rent |  2 | 
| water |  2 | 
| housing |  3 | 
+---------+----------+ 

Notez comment la table users_needs définit la relation entre un utilisateur et un ou plusieurs besoins (ou pas du tout, comme pour le numéro de l'utilisateur 4.)

pour normaliser votre base de données plus loin, vous devez également utiliser une autre table appelée needs, et comme suit:

-- TABLE: needs 

+---------+---------+ 
| need_id | name | 
+---------+---------+ 
|  1 | housing | 
|  2 | water | 
|  3 | food | 
|  4 | rent | 
+---------+---------+ 

Ensuite, la table users_needs devrait simplement se référer à un candidate key de la table needs au lieu de répéter le texte.

-- TABLE: users_needs (instead of the previous one) 

+---------+----------+ 
| need_id | user_id | 
+---------+----------+ 
| 1  |  1 | 
| 2  |  1 | 
| 3  |  1 | 
| 1  |  2 | 
| 4  |  2 | 
| 2  |  2 | 
| 1  |  3 | 
+---------+----------+ 

Vous pouvez également être intéressé à vérifier l'article de Wikipedia suivant pour plus lire sur la répétition des valeurs à l'intérieur des colonnes:


MISE À JOUR:

Pour répondre pleinement à votre question, si vous suivez les directives ci-dessus, le tri, le comptage et l'agrégation des données devraient alors devenir directs.

Pour trier le jeu de résultats en fonction des besoins, vous seriez en mesure de faire ce qui suit:

SELECT  users.name, needs.name 
FROM  users 
INNER JOIN needs ON (needs.user_id = users.user_id) 
ORDER BY needs.name; 

Vous aussi pouvoir compter combien de besoins de chaque utilisateur a sélectionné, par exemple:

SELECT  users.name, COUNT(needs.need) as number_of_needs 
FROM  users 
LEFT JOIN needs ON (needs.user_id = users.user_id) 
GROUP BY users.user_id, users.name 
ORDER BY number_of_needs; 
Questions connexes