0
votes

Rangement de tri

J'ai une table comme ci-dessous, xxx pré>

ici, je veux trier la ligne d'enregistrement sage. p>

Sortie attendue. P>

insert into @tab
select '4','6','1' union
select '6','4','1' union
select '1','2','3'  union
select '2','1','3'  union
select '3','1','2' union
select '4','2','3'  union
select '1','4','6' union

select '5','5','1' union
select '5','5','1' union

select 'a','2','2' union
select '2','a','2' union
select '2','2','a'



;with CTE as(
    Select Case When ascii(Col1) <=  ascii(Col2) And  ascii(Col1) <=  
                     ascii(Col3) Then  cast(Col1 as varchar)
                When ascii(Col2) <=  ascii(Col1) And  ascii(Col2) <=  
                     ascii(Col3) Then  cast(Col2 as varchar)
                Else cast(Col3 as varchar) END as  col1,
                case when ( ascii(col1) >=  ascii(col2) and  ascii(col2) >=  
                            ascii(col3)) or ( ascii(col3) >=  ascii(col2) and  
                            ascii(col2) >=  ascii(col1)) then cast(Col2 as 
                            varchar) 
               when ( ascii(col1) >=  ascii(col3) and  ascii(col3) >=  
                      ascii(col2)) or ( ascii(col2) >=  ascii(col3) and  
                      ascii(col3) >=  ascii(col1)) then  cast(Col3 as varchar)
               when ( ascii(col3) >=  ascii(col1) and  ascii(col1) >=  ascii(col2)) or ( ascii(col2) >=  ascii(col1) and  ascii(col1) >=  ascii(col3)) then cast(Col1 as varchar) end as col2,
                Case When  ascii(Col1) >=  ascii(Col2) And  ascii(Col1) >=  ascii(Col3) Then  cast(Col1 as varchar)
                When  ascii(Col2) >=  ascii(Col1) And  ascii(Col2) >=  ascii(Col3) Then  cast(Col2 as varchar)
                Else  cast(Col3 as varchar) END as col3
    From   @tab)

    select * from CTE


5 commentaires

Comment cela trie je veux dire quelle est la logique derrière?


Pourquoi une première ligne?


Si la rangée 2 a commencé comme (2, 7,3) au lieu de (2,1,3) comme si elle est maintenant, je suppose que le résultat devrait être (2, 3, 7), mais quelle ligne devrait-elle être dans la table finale- Rangée 2 ou en bas?


Cela ne devrait pas être évité. C'est une question complètement légitime. Ce n'est pas parce que la réponse est "Vous ne devriez pas faire cela" ne signifie pas que la question n'est pas claire et sur le sujet pour le site.


Cela semble être un mauvais design


5 Réponses :


0
votes

Utiliser le cas lorsqu'il est comme ci-dessous

select case when col1>col2>col3 then col1
        when col2>col3 then col2
        else col3 end as col1, -- this is the condition for first column


0 commentaires

0
votes

Si toutes les colonnes sont de type entier, la requête ci-dessous fonctionne,

SELECT c1 = CASE
  WHEN c1 <= c2 AND c1 <= c3 THEN c1
  WHEN c2 <= c1 AND c2 <= c3 THEN c2
  ELSE c3 END,
c2 = CASE 
  WHEN c1 <= c2 AND c1 <= c3 THEN 
    CASE WHEN c2 <= c3 THEN c2 ELSE c3 END
  WHEN c2 <= c1 AND c2 <= c3 THEN
    CASE WHEN c1 <= c3 THEN c1 ELSE c3 END
  ELSE
    CASE WHEN c1 <= c2 THEN c1 ELSE c2 END
  END,
c3 = CASE
  WHEN c1 >= c2 AND c1 >= c3 THEN c1
  WHEN c2 >= c1 AND c2 >= c3 THEN c2
  ELSE c3 END
FROM temp_x;


0 commentaires

2
votes

Ce besoin de tri de ligne est généralement un signe que vos tables pourraient bénéficier d'une nouvelle structure. Qu'essayez-vous vraiment d'accomplir? Cela peut probablement être mieux fait en normalisant Col1, Col2 et Col3 pour avoir l'air plus vertical (c'est ce que le CTE «non pivoté» forçant ci-dessous, mais la table devrait ressembler à une chose comme ça en premier lieu).

Si vous Doit faire cela, envisager d'ajouter un identifiant de ligne (essentiellement une clé primaire) à votre table. xxx

alors vous pouvez éviter un tas d'énoncés de cas et aller plus facilement à plus de trois colonnes avec quelque chose comme ce qui suit: xxx

Vous pouvez le voir en action ici .


4 commentaires

es-tu un sorcier?


Lorsque j'utilise le type de données comme Varchar, il renvoie l'erreur comme "le type de colonne" Col3 "en conflit avec le type d'autres colonnes spécifiées dans la liste des impactifs."


Aww merci @manfredwippel. Mais si vous connaissez des pivots et des impulsions, ce n'est pas trop magique. Malheureusement, j'ai travaillé dans des environnements avec des données gravement non normalisées, donc je les ai beaucoup utilisées.


@Mano, il y a une autre façon d'improviser. J'ai changé à cela dans ma réponse. Il a le même effet que c'est moins limitatif lors de la conversion des valeurs pour vous.



2
votes

Une autre façon de le faire en utilisant Row_Number () Comme suivant xxx

ou à l'aide de CTE comme suit. xxx

Démo en ligne


3 commentaires

Cela renvoie des valeurs nulles dans une partie de la colonne.


Veuillez insérer une ligne comme '5', '1', '5'


Vous pouvez consulter la requête mise à jour ici .. REXTESTESTER.COM/STKZ87454



0
votes

Le moyen le plus rapide est probablement des expressions , mais qui ne général est pas généralisée.

i irait pour appliquer comme bon équilibre entre performance et évolutivité : xxx

Ceci peut également gérer facilement les valeurs NULL et les liens, ce qui compliquent considérablement une approche


0 commentaires