2011-02-04 5 views
0

J'ai une table avec environ 15 colonnes. Ce que j'aimerais pouvoir faire, c'est choisir une gamme d'identifiants et avoir toutes les données de colonne identiques qui me sont présentées.SQL trouver les mêmes données de colonne

A la minute, je l'ai structuré comme suit:

SELECT id, col_a, col_b ... count(id) 
FROM table 
GROUP BY col_a, col_b ... 

qui renvoie des lignes regroupées qui ont des données identiques au sein de toutes les lignes - qui est la moitié de ce que je veux, mais idéalement, je voudrais être capable d'obtenir une seule ligne avec soit la valeur (si c'est la même chose pour chaque identifiant de ligne) ou NULL s'il y a une seule différence. Je ne suis pas sûr que ce soit possible, mais je préférerais voir si c'est faisable dans une requête SQL plutôt que d'écrire une logique de bouclage pour que PHP vérifie et vérifie la similarité de chaque ligne.

Merci,

Dan

MISE À JOUR:

Juste pour garder cette mise à jour, j'ai travaillé à travers le problème en écrivant une fonction PHP qui trouverait qui étaient en double, puis affichage les différences. Cependant j'ai maintenant fait depuis une table pour chaque colonne, et ai fait les colonnes comme références aux autres tables.

E.G. Dans MainTable, ColA se réfère maintenant au tableau ColA

Je résous encore le problème avec le PHP pour l'instant, principalement car je pense qu'il laisse encore le problème mentionné ci-dessus, mais au moins maintenant Im ne stocke pas l'information en double .

+0

Je me demande si vous ne devriez pas factoriser votre architecture de base de données? L'idée d'avoir une base de données relationnelle est d'empêcher le stockage des mêmes données dans des endroits différents. Il peut y avoir une raison parfaitement valable pour faire de telles choses cependant. L'entrée de l'utilisateur me vient à l'esprit ... mais je validerais les données avant de les stocker dans un db. – Peter

+0

Elle est basée sur une bibliothèque d'images et chaque image est associée à des données. Certaines images partagent les mêmes données, et lors de la modification des données de plusieurs images, les personnes pour lesquelles je le fais veulent que toutes les informations qui sont les mêmes soient affichées pour elles. – Dan

+0

Un exemple de la structure réelle de la table ainsi que des données réelles serait grandement apprécié. En ce moment, votre table semble souffrir de grandes failles de structure et d'idées fausses. –

Répondre

0

Son une __gVirt_NP_NN_NNPS<__ chose poilue à faire, mais vous pouvez le faire de façon similaire à comment David Martensson a suggéré, je l'écrire comme ça, cependant:

Select a.id, a.col1, a.col2, a.col3 
FROM myTable a, myTable b 
WHERE a.id != b.id 
and a.col1 = b.col1 
and a.col2 = b.col2 
and a.col3 = b.col3 

qui vous donnera les ids qui sont uniques, mais chaque résultat aurait les mêmes valeurs colonnes 1, 2 et 3. Cependant, je suis d'accord avec certains intervenants à votre question selon laquelle vous devriez envisager une autre structure de données, car cela pourrait mieux tirer parti d'un modèle de SGBDR. Dans ce cas, vous voulez avoir 2 tables:

Nom de la table: MyTableIds champs: id, attrId

Nom de la table: MyTableAttrs champs: attrId, attr1, attr2, attr3, ect

Dans En général, si vous avez des données qui vont être dupliquées pour plusieurs enregistrements, vous devez les placer dans une seconde table et créer une relation de sorte que vous ne deviez stocker les données dupliquées qu'une seule fois et les référencer plusieurs fois.

0

Faire une jointure à une sous-requête avec le groupe par:

SELECT a.id, b.col_a, b.col_b ... b.count) 
FROM table a 
LEFT JOIN (
    SELECT id, col_a, col_b ... count(id) "count" 
    FROM table GROUP BY col_a, col_b ... 
)b on a.id = b.id 

De cette façon, la partie extérieure sélectionnera toutes les lignes.

Si vous voulez encore des réponses de groupe, vous pouvez utiliser une UNION au lieu

SELECT id, col_a ... 
WHERE id NOT IN ("SUBQUERY WITH GROUP BY") 
UNION 
"SUBQUERY WITH GROUP BY" 

Pas la plus belle solution, mais il devrait fonctionner

0

Il semble faisable de la façon dont j'ai compris votre question.

Et voici un modèle possible:

SELECT 
    /* GROUP BY columns */ 
    col_A, 
    col_B, 
    ... 

    /* aggregated columns */ 
    CASE MIN(col_M) WHEN MAX(col_M) THEN MIN(col_M) ELSE NULL END, 
    CASE MIN(col_N) WHEN MAX(col_N) THEN MIN(col_N) ELSE NULL END, 
    ... 
    COUNT(...), 
    SUM(...), 
    WHATEVER(...), 
    ... 
FROM ... 
GROUP BY col_A, col_B, ... 
+1

WHATEVER() est implémentée silencieusement. C'est la fonction qui s'exécute lorsque vous avez des colonnes dans la clause SELECT qui ne sont pas dans une clause GROUP BY. (toux) –

+0

@Catcall: En fait oui, vous avez raison, merci! D'une façon ou d'une autre cela ne m'a pas traversé l'esprit quand je composais ce nom joculaire pour un agrégat arbitraire. Je dois être plus prudent la prochaine fois. –

Questions connexes