6
votes

SQL: Obtenez au moins la troisième plus grande valeur d'un ensemble de colonnes d'une rangée

J'ai besoin d'une seule requête SQL pour obtenir la deuxième plus grande valeur d'un ensemble de colonnes d'une ligne. Par exemple, si ce sont des lignes de ma table: xxx

pour Rowid 1 - J'ai besoin de la valeur 9, Rowid 2 - J'ai besoin de la valeur 14


1 commentaires

Et s'il y a deux plus grandes valeurs, par exemple. Pour Rowid 2, col2 = 54 ? Si le résultat doit être 54 ou 13?


3 Réponses :


0
votes
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);
This gives you the second largest integer value in a specific column.EDIT:
then just swap the rows with the columns before doing that. But if the columns are dynamic, it could be quite tricky. The best/easiest way would be to use a client side language and not SQL directly for this specific operation. If not possible, check this: Transpose rows and columns without aggregate

2 commentaires

C'est correct. Mais il a besoin de faire cette croix toutes les colonnes, c'est la deuxième plus grande valeur des n colonnes.


Je pense qu'il veut avoir la deuxième colonne la plus élevée de chacune rangée



3
votes

Vous pouvez le faire par impouverer les données, puis appliquer un numéro de ligne à chaque enregistrement dans le groupe ID . L'impublard prend les données de la disposition de la colonne et les place en lignes afin qu'il soit plus facile de déterminer la deuxième valeur la plus élevée: xxx

voir SQL violon avec la démo

Le résultat montrera: xxx


3 commentaires

Hmm, votre solution pourrait ne pas renvoyer la valeur correcte, si la valeur la plus importante apparaît à deux reprises: sqlfiddle.com/ #! 2/16139/1


@LukaSeder corrigé, nécessitait une vérification supplémentaire pour être sûr que la valeur précédente ne correspond pas à la valeur actuelle.


Super! Et j'ai appris quelque chose sur les variables utilisateur. Je me demande si elles peuvent être généralement utilisées pour la simulation de fonctions SQL Standard Windows, par ex. Fonctions de classement



5
votes

J'ai bien peur que, sans expressions de table et / ou fenêtre de fenêtre communes et sans recourir à la rédaction d'une procédure, cela devient horriblement verbeux dans MySQL

SELECT t.id, t.val second_largest
-- unpivot your columns into a table
FROM (
  SELECT id, col1 val FROM my_table UNION ALL
  SELECT id, col2     FROM my_table UNION ALL
  SELECT id, col3     FROM my_table UNION ALL
  SELECT id, col4     FROM my_table UNION ALL
  SELECT id, coln     FROM my_table
) t

-- retain only those records, where there exists exactly one record with a
-- column value greater than any other column value with the same id
WHERE 1 = (
  SELECT COUNT(*) 
  -- Here, use unions to be sure that every value appears exactly once
  FROM (
    SELECT id, col1 val FROM my_table UNION
    SELECT id, col2     FROM my_table UNION
    SELECT id, col3     FROM my_table UNION
    SELECT id, col4     FROM my_table UNION
    SELECT id, coln     FROM my_table
  ) u
  WHERE t.id = u.id
  AND t.val < u.val
)


2 commentaires

+1 Nous avons eu la même pensée à l'impulsion des données. J'aime les vôtres sans les variables utilisateur. La seule chose est que vous devez improvoir deux fois.


@bluefeet: Ouais, même pensée. Mon mysql sais comment ne va pas assez pour utiliser ces variables. Votre solution est probablement mieux cependant, d'une perspective de performance. Et merci pour la tête-up avec le schéma Sqlfiddle ;-)