mardi 5 mai 2015

SQL - Aggregate Function for DATEDIFF and WHERE/HAVING

I'm trying to query a DB to find the closest date to the parameter I passed in.

I have a problem I've been working on in IRC and lists for a while and can't find a solution. I'm using a python DBAPI (sqlalchemy) and am accessing the data both through CLI and a Flask App (but this should not impact the SQL). The database is MySQL with an InnoDB engine.

The query will depend on the a factor called target_expiration, but for which the value will frequently not exist in the DB. I need to find which value is nearest. For example, I will pass in target_date='2015-06-02' and would expect it to return to me both the 2015-06-03 result and the 2015-06-01 result that is one day away from my target_date.

Attempt at a solution:

SELECT * FROM table1 HAVING MIN(ABS(DATEDIFF(table1.Expiration, 
'2015-06-02'))) = ABS(DATEDIFF(table1.Expiration, '2015-06-02'));

This returns no rows. I can run the same MIN(ABS(DATEDIFF(...))) to return a scalar() and it succeeds and prints a value.

I tried using the HAVING function in order to use an aggregate function. I'm looking to scan the DB and find out what is my closest Expiration date to my target date. If it's zero, I'm done - I've found the date and I then just want to return all dates that match. If it's a day away, I don't know if it's a day forward or a day backwards (I'll deal with adding more functionality to choose later, but for now I'd just like to return all values that are n days away forwards or backwards).

Example Data: table1

This is an extremely limited sample of the data, in reality I have ~40 columns and billions of rows, so speed is a factor.

+------------+-------------+-------+
| Expiration | ProductType | Price |
+------------+-------------+-------+
| 2015-06-01 |      2      |   25  |
+------------+-------------+-------+
| 2015-06-03 |      1      |   22  |
+------------+-------------+-------+
| 2015-05-28 |      1      |   22  |
+------------+-------------+-------+
| 2015-05-28 |      2      |   28  |
+------------+-------------+-------+
| 2015-05-28 |      1      |   22  |
+------------+-------------+-------+
| 2015-06-04 |      2      |   28  |
+------------+-------------+-------+
| 2015-05-25 |      1      |   22  |
+------------+-------------+-------+
| 2015-05-25 |      2      |   28  |
+------------+-------------+-------+

Aucun commentaire:

Enregistrer un commentaire