2010-09-26 4 views
2

Je ne suis même pas sûr que cela soit possible, mais je souhaite commander une requête basée sur la valeur maximale de l'une des trois colonnes.Ordre par valeur maximale dans trois colonnes différentes

structure de la table Exemple: guid, colonne1, colonne2, colonne3

Colonnes 1-3 ont des valeurs numériques et je veux commander l'instruction select en fonction de la valeur maximale de 1, 2 ou 3.

Par exemple:

record column1 column2 column3  
--------------------------------- 
1  5  0  2 
2  2  0  6 
3  0  1  2 

serait-commander fiche 2, 1, 3 parce que 6 est la valeur maximale des trois champs à travers les trois dossiers, fiche 1 est le deuxième et l'enregistrement 3 est le troisième.

Est-ce que cela a un sens?

Merci.

+0

Vous ne pouvez pas 'ORDER BY MAX (colonne1, colonne2, colonne3) '? – Gabe

+0

TSQL (Sybase ou SQL Server) est l'un des rares qui * ne supporte pas les fonctions les plus GRANDE (et MOINS) ...:/ –

+0

En fait, je cherche à utiliser MySQL qui, je le vois, supporte le " la plus grande "fonction". C'est plutôt lent. – Tom

Répondre

3

Il peut être possible de le faire dans une requête de sélection (éventuellement en utilisant quelque chose comme case when si je ne suis pas sûr que cela soit autorisé dans la même clause order by, YMMV selon le SGBD) mais il est rarement une bonne idée d'utiliser calculs par ligne si vous voulez que votre base de données évolue bien au fur et à mesure que les tables grossissent ("ne pas avoir les performances d'un cochon unijambiste dans une course de chevaux", comme le dit avec éloquence un de nos DBA). Dans des situations comme celle-ci, j'ai mis en place une colonne supplémentaire (indexée) pour maintenir le maximum et assurer le maintien de l'intégrité des données en utilisant un déclencheur insert/update pour forcer cette nouvelle colonne au maximum des trois autres. Comme la plupart des tables de base de données sont lues beaucoup plus souvent que écrites, cela amortit le coût du calcul sur toutes les lectures. Le coût est supporté uniquement lorsque les données sont mises à jour et les requêtes deviennent incroyablement rapide puisque vous commande sur un seul, indexé, colonne:

select f1, f2, f3 from t order by fmax desc; 
+0

Ceci est une bonne solution. Je viens de découvrir le plus grand sous MySQL mais c'est plutôt lent. Peut utiliser cette solution si le coût fonctionne mieux. – Tom

+0

Dépend de la taille de la table et de la fréquence relative des sélections et des insertions, mais si votre solution doit être mise à l'échelle, cela est judicieux. GREATEST est assez bon pour les tables que vous savez ne vont pas grandir. – SamStephens

+0

C'est une table d'environ 4500 enregistrements mais cette table ne cessera de croître. À l'heure actuelle en utilisant GREATEST coûte environ 8 secondes pour retourner le jeu d'enregistrements qui est inacceptable. Je vais supposer que le coût de mise à jour d'un autre champ avec le maximum de ces trois à chaque fois que l'un des trois est mis à jour est inférieur à cela. – Tom

1

Comme mentionné here, ce que vous voulez est un équivalent de la fonction GREATEST .

En l'absence de cela, et vous avez défini une hypothèse où l'UDF LargerOf pour revenir le plus grand de deux nombres, utilisez

SELECT * 
FROM Table 
ORDER BY LargerOf(LargerOf(column1, column2), column3) 
+1

Merci, j'aurais dû mentionner que j'utilise MySQL qui a le plus GRAND. Je n'en ai jamais entendu parler avant aujourd'hui! – Tom

+0

Hahaha, je n'ai même pas regardé correctement, pour une raison que je suppose que vous utilisiez TSQL. Mon erreur :) – SamStephens

+0

Non, je l'ai changé en MySQL. Avait comme T-SQL comme je pensais que T-SQL était indépendant de la plate-forme et décrit le langage de SQL =) – Tom

1
create table myTable 
(column1 int, column2 int, column3 int) 
go 


insert into myTable 
values (5, 0 , 2) 
go 

insert into myTable 
values (2, 0 , 6) 
go 

insert into myTable 
values (0, 1 , 2) 
go 


select * 
from mytable 
order by case when column1 > column2 and column1 > column3 then column1 
when column2 > column3 then column2 
else column3 end desc 
+0

Cela fonctionne totalement, merci. Aller à utiliser plus GRAND si, jamais entendu parler avant aujourd'hui =) – Tom

+0

Greatest() n'est pas un serveur SQL intégré dans la fonction - c'est Oracle. Vous pouvez facilement créer les vôtres, mais vous devez savoir comment faire le tri avec une instruction CASE. – JBrooks

+0

GREATEST est supporté par MySQL et PostgreSQL, y compris Oracle. SQLite fournit des fonctionnalités similaires en utilisant MAX: 'MAX (col1, col2, col3)' –

Questions connexes