J'ai des problèmes pour combiner la concaténation avec la commande par PostGre (9.1.9).
Disons, j'ai des frontières de table avec 3 champs: Les deux premiers champs sont des codes des pays et le troisième est la longueur de la frontière entre ces pays. Je dois composer une sélection d'une colonne qui aurait des valeurs uniques pour toute la table, de plus, cette colonne doit être sélectionnée dans l'ordre décroissant.
Pour cela, je concaténate les champs clés avec un caractère de séparateur, sinon deux rangées différentes pourraient donner le même résultat, comme (AB, C et A, BC). P> Alors je cours la requête suivante: P> Cependant, dans le résultat, je vois que le caractère "_" est ometté du tri.
Les résultats ressemblent à ceci: p> Vous pouvez voir que le résultat est trié comme si "_" n'existe pas dans les cordes. P> si J'utilise une lettre (disons 'x') en tant que séparateur - la commande est correcte. Mais je dois utiliser un caractère spécial qui n'apparaît pas dans les champs pays1 et pays2, pour éviter les contentions. P> Que dois-je faire, afin de rendre le caractère "_" à prendre en compte pendant Le tri. p> Il s'est avéré que la concaténation n'a rien à voir avec le problème. Le problème est que la commande en ignore simplement "_" caractère. P> p>
La clé principale est définie sur les deux premiers champs. P>
Modifier h3>
3 Réponses :
Que se passe-t-il lorsque vous faites ce qui suit?
select country_group from ( select country1||'_'||country2 as country_group from borders ) a order by country_group
J'ai mis à jour la question que si j'utilise une lettre comme séparateur, la commande est correcte, le problème n'est donc pas dans l'ordre par 1 code>
Juky, assez juste. Essayez la suggestion éditée comme mentionné et commandez cependant que vous le souhaitez. On dirait que la réponse de @ romain fonctionnerait bien aussi.
juste commander par les deux colonnes: sauf si vous n'utilisez que des agrégats ou des fenêtres, PostgreSQL permet de commander par colonnes même si vous n'inclut pas les figures dans la liste Sélectionner. P > Comme suggéré dans une autre réponse, vous pouvez également modifier la collaison de la colonne combinée, mais, si vous le pouvez, le tri sur des colonnes ordinaires est plus rapide, surtout si vous avez un index sur eux. P> P>
Je crains que cela n'atteignait pas tous les cas. Je vais vérifier cela plus loin. Merci pour une simple suggestion.
La requête est correcte et il «attrapera tous les cas». La question plus importante est la raison pour laquelle PostgreSQL se comporte de cette façon.
Cela ne fonctionnerait pas. Par exemple, vous avez deux rangées ("A B", "C") et ("A", "B"). Dans votre solution, la deuxième ligne irait avant le premier. Mais vraiment, la chaîne "A_B" devrait aller après "A B_C". ping @robertco.
@Robertco La plus grande question est de savoir pourquoi PostgreSQL se comporte-t-il de cette façon. Code> Cela me dérange aussi.
@ Jutky qu'entendez-vous par "Caêrer de cette façon"? L'ordre de tri est défini par la collation afin que l'ordre des lignes devrait dépendre seulement i> dessus.
@fog Oui, c'est quelque chose que je n'ai pas connu. Merci.
select country1 || '_' || country2 collate "C" as a from borders order by 1 sql fiddle demoNotes according to discussion in comments:1.) COLLATE "C" applies in the ORDER BY clause as long as it references the expression in the SELECT clause by positional parameter or alias. If you repeat the expression in ORDER BY you also need to repeat the COLLATE clause if you want to affect the sort order accordingly.sql fiddle demo2.) In collations where _ does not influence the sort order, it is more efficient to use fog's query, even more so because that one makes use of the existing index (primary key is defined on the first two fields). However, if _ has an influence, one needs to sort on the combined expression:sql fiddle demoQuery performance (tested in Postgres 9.2): sql fiddle demoPostgreSQL Collation Support in the manual.
Bien, maintenant le caractère spécial est pris en compte, mais il est trié après i> les lettres. Pourquoi est-ce que le code ASCII de '_' est inférieur au code ASCII des lettres?
Oh, je vois, les personnages ne sont pas triés par les codes ASCII. Ils sont triés par les paramètres locaux et les lettres vont avant les caractères spéciaux. Existe-t-il un moyen de trier la chaîne par code ASCII des caractères?
@ Jutky je pense que le meilleur moyen est d'aller avec la solution de brouillard
Cela n'a pas attrapé tous les cas, comme j'ai commenté sa réponse.
@ Jutky HM, code ASCII de Underscore est 95 - Theasciicode.com.ar/ascidi-printable-Caractérents/.../a> Donc, c'est plus que des lettres majuscules
Oui, vous avez raison, pour les majuscules et le soulignement, il n'y aurait pas de problème. Mais le code de soulignement ASCII est moins minuscule. Aussi loin que j'ai trouvé, dans "C" locale, cela ne tient pas.
Oui, vous êtes correct, merci pour un soutien durable :) Voici le document officiel qui vous aide à tester: pubs.opengroup.org/onlinepubs/7908799/XBD/locale.html
Cela fonctionnerait mal en comparaison, encore plus que, selon la question, la clé primaire est définie sur les deux premiers champs code>. Cette requête ne pouvait pas utiliser l'index, tandis que la requête de brouillard le ferait.
@Erwinbrandsetter C'est pourquoi j'ai dit qu'il vaut mieux aller avec la réponse au brouillard, mon objectif était de trouver pourquoi le tri ne fonctionne pas et de trier les chaînes avec '_'.
Eh bien, le fait qu'il n'y ait aucune explication de votre solution (ce qui s'avère de ne pas résoudre le problème tout en gratifiant la performance) y ajoute. Vous écrivez beaucoup de bonnes réponses. Ce n'est pas l'un d'eux.
Eh bien opt besoin de trier les lignes par pays1_country2, non par pays1, pays2, comme il l'a dit dans les commentaires à la réponse au brouillard - Par exemple, c'est que vous avez deux lignes ("AB", "C") et ("A", " B "). Dans votre solution, la deuxième ligne irait avant le premier. Mais vraiment, la chaîne "a_b" devrait aller après "A b_c" i> - SQLFIDDLE. com / #! 1 / 50f30 / 2
@Erwinbrandsetter et c'est la fin, oui en théorie, cela nuit à la performance, j'ai vérifié les plans, merci. Mais dans la vraie vie, il y aurait une terrible différence? - J'ai vérifié cela sur 1000000 rangées et je ne peux pas voir la grande différence sur tout - SQLFIDDLE .com / #! 1 / BD6C3 / 1 . Quoi qu'il en soit, merci pour la pointe de l'index. Je dois y aller.
@Erwinbrandsetter je ne comprends pas le besoin de bowvote. Même si la solution n'utilise pas d'index, au moins résout le problème. Contrairement à la réponse de la brouillard.
Supprimer mon bowvote en raison de votre considération valable concernant l'influence potentielle de '_' code> sur l'ordre de tri. Mais vraiment, cela doit entrer dans la réponse, pas seulement dans les commentaires! J'ai monté la réponse et j'ai ajouté des informations pour clarifier tout en étant à ce sujet.
Performance B> Test: SQLFIDDLE.com/#!1/BD6C3/1 . A plusieurs limitations: 1) utilise uniquement des mots avec 1 ou deux caractères (seuls chiffres). 2) Le test est sous Postgres 9.1, qui correspond au Q mais 9.2+ est plus intéressant en raison des indices de couverture. 3) Ce n'est pas tout à fait tester ce que vous pourriez penser. Commander par code> répète l'expression sans
Assembler code>. Reportez-vous à l'explication que j'ai ajoutée à la réponse ci-dessus. Test alternatif avec des lignes 50K: SQLFIDDLE.COM/#!12/8122D/1
BTW, merci les gars pour le lien avec SQLfiddle. Je ne connaissais pas cette ressource utile.
Le caractère
_ code> peut être pertinent pour le tri ou non, En fonction de vos paramètres de collement.
Merci, c'est quelque chose que je n'ai pas connu et que je l'ai appris des réponses ici.