Valeurs de colonne dans une ligne
-
13-11-2019 - |
Question
J'ai un tableau suivant
id count hour age range
-------------------------------------
0 5 10 61 10-200
1 6 20 61 10-200
2 7 15 61 10-200
5 9 5 61 201-300
7 10 25 61 201-300
0 5 10 62 10-20
1 6 20 62 10-20
2 7 15 62 10-20
5 9 5 62 21-30
1 8 6 62 21-30
7 10 25 62 21-30
10 15 30 62 31-40
J'ai besoin de sélectionner des valeurs distinctes de la plage de colonnes que j'ai essayé de suivre la requête
Select distinct range as interval from table name where age = 62;
Son résultat est dans une colonne comme suit:
interval
----------
10-20
21-30
31-41
Comment puis-je obtenir des résultats comme suit?
10-20, 21-30, 31-40
Édité: j'essaie maintenant de suivre la requête:
select sys_connect_by_path(range,',') interval
from
(select distinct NVL(range,'0') range , ROW_NUMBER() OVER (ORDER BY RANGE) rn
from table_name where age = 62)
where connect_by_isleaf = 1 CONNECT BY rn = PRIOR rn+1 start with rn = 1;
Qui me donne la sortie comme:
Interval
----------------------------------------------------------------------------
, 10-20,10-20,10-20,21-30,21-30, 31-40
Les gars plz m'aident à obtenir la sortie souhaitée.
La solution
Si vous êtes sur 11.2 plutôt que seulement 11.1, vous pouvez utiliser le LISTAGG
fonction d'agrégation
SELECT listagg( interval, ',' )
WITHIN GROUP( ORDER BY interval )
FROM (SELECT DISTINCT range AS interval
FROM table_name
WHERE age = 62)
Si vous utilisez une version antérieure d'Oracle, vous pouvez utiliser l'un des autres Techniques d'agrégation de chaînes Oracle Sur la page de Tim Hall. Avant 11.2, ma préférence personnelle serait de créer un fonction agrégée définie par l'utilisateur pour que vous puissiez alors
SELECT string_agg( interval )
FROM (SELECT DISTINCT range AS interval
FROM table_name
WHERE age = 62)
Si vous ne souhaitez pas créer de fonction, cependant, vous pouvez utiliser le ROW_NUMBER et SYS_CONNECT_BY_PATH Bien que cela a tendance à devenir un peu plus difficile à suivre
with x as (
SELECT DISTINCT range AS interval
FROM table_name
WHERE age = 62 )
select ltrim( max( sys_connect_by_path(interval, ','))
keep (dense_rank last order by curr),
',') range
from (select interval,
row_number() over (order by interval) as curr,
row_number() over (order by interval) -1 as prev
from x)
connect by prev = PRIOR curr
start with curr = 1