Question

I have a database structured in the following way

ID | DATE | col_0        |
--------------------------
1  | 2014 | A_Ver2_data0 |
2  | 2014 | A_Ver2_data1 |
3  | 2014 | A_Ver2_data2 |
4  | 2013 | A_Ver1_data0 |
5  | 2013 | A_Ver1_data1 |
6  | 2012 | A_Ver0_data0 |
7  | 2012 | A_Ver0_data1 |
8  | 2013 | B_Ver3_data0 |
9  | 2013 | B_Ver3_data1 |
10 | 2013 | B_Ver3_data2 |
11 | 2010 | B_Ver2_data0 |
12 | 2010 | B_Ver2_data1 |
13 | 2009 | B_Ver1_data0 |
14 | 2007 | B_Ver0_data0 |

I need to write a query that will return the most recent version of the A_ and B_ prefixed data sets. So I was thinking something like SELECT * FROM db.table ORDER BY DATE DESC But I want to filter out expired versions. desired output should be:

ID | DATE | col_0        |
--------------------------
1  | 2014 | A_Ver2_data0 |
2  | 2014 | A_Ver2_data1 |
3  | 2014 | A_Ver2_data2 |    
8  | 2013 | B_Ver3_data0 |
9  | 2013 | B_Ver3_data1 |
10 | 2013 | B_Ver3_data2 |

Any Ideas?

Was it helpful?

Solution

I think this does what you want. It parses the column to get the first and last parts and then finds the maximum "DATE" for each. It returns the row that matches the date:

select id, "DATE", COL_A
from (select v.*,
             max("DATE") over (partition by substr(col_A, 1, 1),
                                            substr(col_A, 8)
                              ) as maxdate
      from versiones v
     ) v
where "DATE" = maxdate;

The SQL Fiddle is here.

OTHER TIPS

I am not sure but i think this would work : "HAVING date >= MAX(date)-1"

max(date)-1 will return 2014-1 = 2013 , which will eventually filter out the results based on date >= 2013 .

But this would list all the 2013,2014 entries ..

You could use an analytic function to get the maximum version, and then select the corresponding records, as below:

SELECT
  *
FROM
  db.table
WHERE
  Col_0 IN
  (
    Select Distinct
      Max(Col_0) Over (Partition By Replace(Col_0, Replace(Regexp_Substr(Col_0, '_[^,]+_'), '_', ''), '') 
                       Order By REPLACE(Regexp_Substr(Col_0, '_[^,]+_'), '_', '') DESC) AS Col_0
    FROM
      db.table
  );

Also, please note that you would not be able to name a column as DATE, because DATE is a reserved word.

Here is my answer:

select * from
versiones
where SUBSTR(COL_A,0,6)
in(
  select version from
  (
  select SUBSTR(COL_A,0,1) letra,max(SUBSTR(COL_A,6,1)) maximo,
  SUBSTR(COL_A,0,1)||'_Ver'||max(SUBSTR(COL_A,6,1)) version
  from versiones
   group by SUBSTR(COL_A,0,1)
  )
  cs
  )

Sqlfiddle: http://sqlfiddle.com/#!4/84a8f/13

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top