2017-10-21 135 views
1

Voici le violon de mon SQL: http://sqlfiddle.com/#!4/75ab7/2Oracle SQL, comment sélectionner la première rangée dans un groupe?

Fondamentalement, j'ai créé une table et j'y insère des données.

CREATE TABLE subject (
    id INT NOT NULL, 
    seq_num INT NOT NULL, 
    name VARCHAR(30) NOT NULL 
); 

INSERT INTO subject 
    (id, seq_num, name) 
VALUES 
    (1, 1, 'sub_1_1'); 

INSERT INTO subject 
    (id, seq_num, name) 
VALUES 
    (2, 1, 'sub_1_2'); 

INSERT INTO subject 
    (id, seq_num, name) 
VALUES 
    (3, 2,'sub_2_1'); 

INSERT INTO subject 
    (id, seq_num, name) 
VALUES 
    (4, 2, 'sub_2_2'); 

INSERT INTO subject 
    (id, seq_num, name) 
VALUES 
    (5, 2, 'sub_2_3'); 

INSERT INTO subject 
    (id, seq_num, name) 
VALUES 
    (6, 3, 'sub_3_1'); 

INSERT INTO subject 
    (id, seq_num, name) 
VALUES 
    (7, 3, 'sub_3_1'); 

Je cours cette instruction select:

select 
    LISTAGG(TRIM(id), ',') WITHIN GROUP (ORDER BY 1) AS IDS, 
    seq_num, 
    LISTAGG(TRIM(name), ',') WITHIN GROUP (ORDER BY 1) AS NAMES 
from 
    subject 
group by 
    seq_num 
order by 
    seq_num asc 

La sélection résultat de l'instruction:

| ids | seq_num | names     | 
|-------|---------|-------------------------| 
| 1,2 | 1  | sub_1_1,sub_1_2   | 
| 3,4,5 | 2  | sub_2_1,sub_2_2,sub_2_3 | 
| 6,7 | 3  | sub_3_1,sub_3_1   | 

Puis-je générer quelque chose comme ça?

| ids | seq_num | names | 
|-----|---------|---------| 
| 1 | 1  | sub_1_1 | 
| 3 | 2  | sub_2_1 | 
| 6 | 3  | sub_3_1 | 

Cela ne prend que la première ligne d'un groupe.

Répondre

1

Vous pouvez utiliser keep et first dans l'oracle:

select seq_num, 
     max(trim(id)) keep (dense_rank first order by trim(id)) as first_id, 
     max(trim(name)) keep (dense_rank first order by trim(id)) as first_name 
from subject 
group by seq_num 
order by seq_num asc; 

Here est le SQL Fiddle.

+0

Pouvez-vous expliquer l'importance d'utiliser Trim() ici? –

+1

@Harshil. . . C'est une question pour le PO et devrait être posée sur la question. Le 'trim()' est utilisé dans le code de la question. –

+0

Ok .. merci pour la réponse rapide cependant. –

2

Utilisez le numéro de ligne:

select 
    id, seq_num, name 
from 
(
    select id, seq_num, name, 
     row_number() over (partition by seq_num order by id) rn 
    from subject 
) t 
where rn = 1 
order by seq_num; 

Voici un lien vers votre Fiddle mise à jour:

Demo

1

Cela devrait fonctionner:

select 
    min(id) AS IDS, 
    seq_num, 
    min(name) AS NAMES 
from 
    subject 
group by 
    seq_num 
order by 
    seq_num asc; 

Working Demo

J'espère que ça aide!