web-dev-qa-db-fra.com

Sélectionnez les valeurs de plusieurs colonnes dans une seule colonne

J'ai une table dans une base de données qui a 9 colonnes contenant le même type de données, ces valeurs sont autorisées à être nulles. J'ai besoin de sélectionner chacune des valeurs non nulles dans une seule colonne de valeurs qui ne se soucient pas de l'identité de la ligne dont elles proviennent.

Donc, pour une table qui ressemble à ceci:

+---------+------+--------+------+
|   Id    | I1   | I2     | I3   | 
+---------+------+--------+------+
|    1    | x1   | x2     |  x7  |
|    2    | x3   | null   |  x8  |
|    3    | null | null   |  null|
|    4    | x4   | x5     |  null|
|    5    | null | x6     |  x9  |
+---------+------+--------+------+

Je souhaite sélectionner chacune des valeurs préfixées par x dans une seule colonne. Mes données résultantes devraient ressembler au tableau suivant. L'ordre doit être préservé, donc la première valeur de colonne de la première ligne doit être en haut et la dernière valeur de colonne de la dernière ligne en bas:

+-------+
| value |
+-------+
|  x1   |
|  x2   |
|  x7   |
|  x3   |
|  x8   |
|  x4   |
|  x5   |
|  x6   |
|  x9   |
+-------+

J'utilise SQL Server 2008 R2. Existe-t-il une meilleure technique pour y parvenir que de sélectionner tour à tour la valeur de chaque colonne, à partir de chaque ligne, et d'insérer les valeurs non nulles dans les résultats?

13
Jason

Vous pouvez utiliser la fonction UNPIVOT pour obtenir le résultat final:

select value
from yourtable
unpivot
(
  value
  for col in (I1, I2, I3)
) un
order by id, col;

Étant donné que vous utilisez SQL Server 2008+, vous pouvez également utiliser CROSS APPLY avec la clause VALUES pour annuler le pivotement des colonnes:

select value
from yourtable
cross apply
(
    values
        ('I1', I1),
        ('I2', I2),
        ('I3', I3)
) c(col, value)
where value is not null
order by id, col
18
Taryn
SELECT value FROM (
   SELECT ID, 1 AS col, I1 AS [value] FROM t
   UNION ALL SELECT ID, 2,  I2 FROM t
   UNION ALL SELECT ID, 3,  I3 FROM t
) AS t WHERE value IS NOT NULL ORDER BY ID, col;
6
LS_ᴅᴇᴠ

Essayez l'union comme ci-dessous:

    select value from
(
    select col1 as value from TestTable
    union
    select col2 as value from TestTable
    union
    select col3 as value from TestTable
) tt where value is not null
4
Upendra Chaudhari