Reputation: 51
I have a data like this in a table:
column1 column2
a 1
a 2
b 2
b 3
a 4
c 5
I want a output like this:
column1 column2
a 1-2
b 2-3
a 4-0
c 5-0
Upvotes: 0
Views: 89
Reputation: 9191
You should be carefull using something like
select column1, column2, rownum from table1
to create some unique ids for your data. Per definition is the ordering without an order by in your SQL not defined. Therefore it is by coincidence that
select * from table1
returns your rows in the ordering you inserted it in your database. As the data grows you will get exceptions to this ordering. So it is highly recommended to put a primary key column in your data table to preserve this insert ordering. I included the column id
for this.
Using this pimped dataset you could get the requested data using this query:
with data_aggr as (
select column1,
case
when lead(column1,1,' ') over (order by id)<>column1
and lag(column1,1,' ') over (order by id)<>column1
then column2 || '-0'
when lead(column1,1,' ') over (order by id)=column1
and lag(column1,1,' ') over (order by id)<>column1
then column2 || '-' || lead(column2,1) over (order by id)
else null
end aggr_col2
from table1)
select column1, aggr_col2 from data_aggr where not aggr_col2 is null
http://sqlfiddle.com/#!4/cd24d/19
Upvotes: 0
Reputation: 3128
Try this query:
with vw1 as
(select table1.*,rownum rn from table1),
vw2 as (select col1,col2,rn,rn - col2 dis from vw1),
vw3 as (select col1,min(rn),to_char(min(col2))||' - '||
case when min(col2) = max(col2) then '0' else to_char(max(col2)) end col2 from vw2
group by col1,dis order by min(rn))
select col1,col2 from vw3;
Upvotes: 2
Reputation: 256
Try this query...
select * from
(
select col1 as column1,case when LEAD(col1 , 1, 0) OVER (ORDER BY col2) = col1
then concat( LEAD(col2 , 1, 0) OVER (ORDER BY col2),'-'||col2)
else (case when lag(col1,1,0) over (ORDER BY col2) <> col1 then
concat(col2,'-'||'0')else '0' end)
end as column2
from table
order by col2
)
where column2<>'0'
;
Upvotes: 0
Reputation: 86765
You haven't really given a lot of information.
- Will there always only be 1 or 2 values in column2, for each value in column1?
- Will column2 always be in order?
- etc, etc?
But, for the given data, the following should give the results you have asked for.
SELECT
column1,
MIN(column2) AS first_column2,
CASE WHEN COUNT(*) = 1 THEN 0 ELSE MAX(column2) END AS final_column2
FROM
(
SELECT
ROW_NUMBER() OVER ( ORDER BY column2, column1) AS sequence_main,
ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2 ) AS sequence_c1,
*
FROM
your_table
)
AS sequenced_table
GROUP BY
sequence_main - sequence_c1,
column1
ORDER BY
MIN(sequence_main)
Example calculations:
column1 column2 | sequence_main sequence_c1 main - c1 | group
a 1 | 1 1 0 | a1
a 2 | 2 2 0 | a1
b 2 | 3 1 2 | b2
b 3 | 4 2 2 | b2
a 4 | 5 3 2 | a2
c 5 | 6 1 5 | c5
Upvotes: 0