2010-04-23 4 views
0

j'ai données comme celui-ciitems de tri en fonction de leur semble compter

d b c

a d

c b

a b

c un

c a d

c

si vous analysez, vous trouverez l'apparence de chaque élément comme suit

a: 4 b: 3 c: 5 d: 2

Selon apparence mes éléments triés seraient être C, a, B, D

et la sortie finale doit être

cbd

a d

c b

a b

c un

c a d

c

Toute idée, comment nous pouvons y parvenir en utilisant la requête SQL?

+0

Ce sont trois colonnes différentes ou une colonne? –

+0

ce sont des colonnes différentes –

+0

les colonnes de vos données affichées représentent-elles des colonnes? si oui, pourquoi sont-ils en train d'être réorganisés? – TerrorAustralis

Répondre

0

À moins qu'une autre colonne ne dicte l'ordre des lignes d'entrée, il ne sera pas possible de garantir que les lignes de sortie sont retournées dans le même ordre. J'ai fait une hypothèse ici pour les ordonner par les valeurs des trois colonnes afin que le résultat soit déterministe.

Il est probablement possible de compacter ce code en moins d'étapes, mais montre les étapes raisonnablement clairement.

Notez que pour un grand ensemble de données, il peut être plus efficace de partitionner certaines de ces étapes en opérations SELECT INTO créant des tables temporaires ou des tables de travail.

DECLARE @t TABLE 
(col1 CHAR(1) 
,col2 CHAR(1) 
,col3 CHAR(1) 
) 

INSERT @t 
     SELECT 'd','b','c' 
UNION SELECT 'a','d',NULL 
UNION SELECT 'c','b',NULL 
UNION SELECT 'a','b',NULL 
UNION SELECT 'c','a',NULL 
UNION SELECT 'c','a','d' 
UNION SELECT 'c',NULL,NULL 


;WITH freqCTE 
AS 
(
     SELECT col1 FROM @t WHERE col1 IS NOT NULL 

     UNION ALL 

     SELECT col2 FROM @t WHERE col2 IS NOT NULL 

     UNION ALL 

     SELECT col3 FROM @t WHERE col3 IS NOT NULL   
) 
,grpCTE 
AS 
(
     SELECT col1 AS val 
       ,COUNT(1) AS cnt 
     FROM freqCTE 
     GROUP BY col1 

) 
,rowNCTE 
AS 
(
       SELECT * 
         ,ROW_NUMBER() OVER (ORDER BY col1 
                ,col2 
                ,col3 
              ) AS rowN 
       FROM @t 
) 
,buildCTE 
AS 
(
     SELECT rowN 
       ,val 
       ,cnt 
       ,ROW_NUMBER() OVER (PARTITION BY rowN 
            ORDER BY  ISNULL(cnt,-1) DESC 
               ,ISNULL(val,'z') 
            ) AS colOrd 
     FROM (       
       SELECT * 
       FROM   rowNCTE AS t 
       JOIN   grpCTE AS g1 
       ON    g1.val = t.col1 

       UNION ALL 

       SELECT * 
       FROM   rowNCTE AS t 
       LEFT JOIN  grpCTE AS g2 
       ON    g2.val = t.col2 

       UNION ALL 

       SELECT * 
       FROM   rowNCTE AS t 
       LEFT JOIN  grpCTE AS g3 
       ON    g3.val = t.col3 
      ) AS x 
) 
SELECT b1.val AS col1 
     ,b2.val AS col2 
     ,b3.val AS col3 
FROM buildCTE AS b1 
JOIN buildCTE AS b2 
ON b2.rowN = b1.rowN 
AND b2.colOrd = 2 
JOIN buildCTE AS b3 
ON b3.rowN = b1.rowN 
AND b3.colOrd = 3 
WHERE b1.colOrd = 1 
ORDER BY b1.rowN 
+0

cette requête donne une erreur d'erreur de mémoire insuffisante pour 10 0r plus de colonnes –

+0

@Anil Mane - dans quel environnement? –

+0

@Anil Mane - avez-vous essayé ma suggestion de sélectionner certaines étapes dans des tables temporaires? –

Questions connexes