Search code examples
sqldatabasedatabase-agnostic

How to group the records according to the range in SQL


Hi I would like to create a SQL to group the records according to the range

For example, suppose I have

Number    Time            Price
100    20100810           10.0
100    20100812           15.0
160    20100810           10.0
200    20100810           12.0
210    20100811           13.0
300    20100811           14.0
350    20100810           16.0

Now I need to get the records according to the range of the "Number": [100,200),[200,300),[300,400) and [0,400]. For each range, I need the "Price" of the lastest "Time"

So the results should be

NumberRange         Time            Price
    1            20100812           15.0
    2            20100811           13.0
    3            20100811           14.0
    4            20100812           15.0

How can I construct a SQL statement to produce this?

I am not working on a specific Database. So I am looking for no specific database SQL statement


Solution

  • Use:

     SELECT x.rank, x.time, x.price
       FROM (SELECT *,
                    CASE 
                       WHEN number BETWEEN 100 and 199 THEN 1
                       WHEN number BETWEEN 200 and 299 THEN 2
                       WHEN number BETWEEN 300 and 399 THEN 3
                       ELSE NULL
                    END AS rank
               FROM TABLE) x
               JOIN (SELECT t.rank,
                            MAX(t.time) AS max_time
                       FROM (SELECT *,
                                    CASE 
                                      WHEN number BETWEEN 100 and 199 THEN 1
                                      WHEN number BETWEEN 200 and 299 THEN 2
                                      WHEN number BETWEEN 300 and 399 THEN 3
                                      ELSE NULL
                                    END AS rank
                               FROM TABLE) t
                   GROUP BY t.rank) y ON y.rank = x.rank 
                                     AND y.max_time = x.time
    UNION ALL
    SELECT x.rank, x.time, x.price
      FROM (SELECT *,
                   CASE 
                     WHEN number BETWEEN 0 and 400 THEN 4
                     ELSE NULL
                   END AS rank
              FROM TABLE) x
              JOIN (SELECT t.rank,
                           MAX(t.time) AS max_time
                      FROM (SELECT *,
                                   CASE  
                                     WHEN number BETWEEN 0 and 400 THEN 4
                                     ELSE NULL
                                   END AS rank
                              FROM TABLE) t
                  GROUP BY t.rank) y ON y.rank = x.rank 
                                    AND y.max_time = x.time