2009-07-16 9 views
2
| one | two | 
------------- 
| A | 1 | 
| A | 2 | 
| B | 1 | 
| B | 3 | 
| C | 1 | 
| C | 4 | 

Je voudrais obtenir aucune répétition dans une colonne dans une requête, de sorte que la norme SELECT DISTINCT one,two FROM table; ou SELECT * FROM table GROUP BY one,two; ne fonctionne pas tout à fait, parce qu'il cherche distincte dans toutes les lignes, ce qui ce cas renverrait toutes les 6 lignes.plusieurs colonnes distinctes dans une base MySQL

Idéalement, je cherche:

| one | two | 
------------- 
| A | 1 | 
| B | 3 | 
| C | 4 | 

En PHP (etc.), je voudrais juste faire avec un tableau pour chaque colonne, et le cas échéant la colonne a été utilisée puis passez la ligne. Cependant, je ne suis pas sûr de savoir comment l'implémenter dans MySQL.

SELECT * FROM (SELECT * FROM table GROUP BY one) GROUP BY two - fonctionne presque. mais parce que la requête externe ne voit pas toutes les alternatives, elle va manquer des options valides, à savoir que l'intérieur s'effondrera à A, B, C mais pourrait bien choisir tous les 1s pour la colonne deux, ce qui signifierait que le second GROUP BY alors réduisez-le propre à 1 rangée!

Je sais que l'ordre de la vérification de la duplication aura un effet sur les lignes exactes renvoyées - ne vous inquiétez pas à ce sujet - je veux juste une bonne section de lignes avec des lignes similaires minimales.

+1

Expliquez votre règle de requête. S'il y a 2 lignes avec le même champ 'one', lequel voulez-vous avoir dans la sortie? –

+0

Dans votre exemple, vous avez sélectionné 'A-1', qui est le premier correspondant, mais dans les deux autres, vous avez choisi les secondes correspondances. Pouvez-vous solidifier votre choix à l'un ou à l'autre? –

+0

En plus de la question de Clément - que se passe-t-il si 'C' dans la première colonne n'apparaît qu'avec les valeurs de la colonne deux qui ont déjà eu lieu avec 'A' et 'B'? – quosoo

Répondre

0

Il n'y a aucun moyen de le faire en SQL: vous pouvez avoir six lignes (chaque ligne), cinq lignes (chaque première utilisation de chaque colonne) ou une ligne (chaque première utilisation de chaque colonne dans les deux colonnes). La raison pour laquelle vous avez du mal à expliquer ce que vous voulez, c'est que c'est basé sur un jugement humain. Vous ne pourrez pas le faire en SQL tant que vous ne serez pas en mesure de le décrire qualitativement en anglais, et ce que vous voulez n'est pas qualitatif, c'est procédural.

Il existe un tas de façons de l'approximer, comme le regroupement par la colonne inférieure puis le tri par nombre de correspondances inverses, mais ils sont tous exploitables. Jusqu'à ce que vous puissiez donner un critère de sélection univoque et logique, cela ne fonctionnera pas. Dire "minimal" ne compte pas jusqu'à ce que vous définissiez minimal, et le minimum que vous semblez vouloir requiert un behvaior agrégé procédural, que vous ne pouvez pas obtenir dans MySQL.

+0

Probablement le plus proche que vous obtiendrez qui n'exclut pas incorrectement les lignes est sélectionnez distinct * de (sélectionnez * du groupe foo par un) comme l union tous (sélectionnez * du groupe foo par deux) comme r; –

+0

Merci pour la réponse, admettre ne pas comprendre la différence entre qualitative et procédurale - tentera de lire sur ces termes ... – barryhunter

1

Eh bien il se trouve que je trouve une réponse;)

CREATE TEMPORARY TABLE table2 ENGINE HEAP SELECT * FROM table;

ALTER IGNORE TABLE table2 ADD UNIQUE (one), ADD UNIQUE (two);

SELECT * FROM table2;

Le IGNORE dans la table alter est importante, car elle supprime simplement toutes les lignes en double basé sur l'index unique s.

(pas sûr pourquoi ne pas penser à cela avant - tel qu'il est utilisé à bon escient dans la résolution de « l'ordre avant le groupe par » requêtes de style)

+0

ou bien sûr dans la requête réelle ont un endroit où et sur la sélection initiale, ce qui le rend utile. Expérimentant différents ordres, RAND() fonctionne bien. – barryhunter

Questions connexes