365 Days of Daily Coding: Day 14

Today’s leetcode challenge was with regards to handling dates in database.

Given the table ‘Weather’, I had to find out the dates that had higher temeperature than the previous dates.

Table: Weather

idrecordDatetemperature
12015-01-0110
22015-01-0225
32015-01-0320
42015-01-0430
Sample of the table ‘Weather’

Expected Output:

id
2
4
Expected output of the challenge

I tried using the function ‘LAG()’ to get temperature of the previous dates. However, this failed in one of the test cases. My solution failed to take account of the fact that the dates may not be consecutive and there could be missing temperature information for one or two dates.

 SELECT id FROM(
             SELECT id, recordDate, Temperature, 
             lag(Temperature) OVER (ORDER BY id) 
             AS prev FROM Weather)
 WHERE temperature > prev; 

Submitted Solution Taken From Forums:

Solution 1

SELECT W1.Id 
FROM Weather W1 
WHERE W1.RecordDate - 1 IN 
     (SELECT W2.RecordDate 
     FROM Weather W2 
     WHERE W1.Temperature > W2.Temperature)

It has been quite taxing trying to understand this query. I asked help from colleague to understand this query. My explanation may not be accurate. If so let me know then.

Query 1

Just like a normal ‘SELECT’ query, the processing sequence follows from the ‘SELECT’ to ‘WHERE’ and then ‘IN’.

SELECT W1.Id 
FROM Weather W1 
WHERE W1.RecordDate - 1
W1.idW1.recordDatew1.Temperature
12015-01-0225
22015-01-0320
32015-01-0430
Sample of the output of Query 1

Query 2

The ‘WHERE’ clause in the subquery then tests the W1.Temperature parameter from the ‘W1’ against the W2.Temperature and only return those records that have higher temperature than ‘W2.recordDate’. The below table is the W1 and W2 tables queried from.

IN (SELECT W2.RecordDate 
     FROM Weather W2 
     WHERE W1.Temperature > W2.Temperature)
W1.idW1.recordDateW1.TemperatueW2.idW2.recordDateW2.Temperature
12015-01-022512015-01-0110
22015-01-032022015-01-0225
32015-01-043032015-01-0320
442015-01-0430
Sample of the output of Query 2

When both the query 1 and query 2 are combined, it returns the ‘id’ that fulfils the condition of W1.Temperature > W2.Temperature.

Solution 2

SELECT DISTINCT a.Id
FROM Weather a,Weather b
WHERE a.Temperature > b.Temperature
AND (a.Recorddate - b.Recorddate) = 1;
 Runtime = 27.43% 

Query 1

The first of the query with the ‘SELECT’ clause is basically a self cross join.

 SELECT *
 FROM Weather a,Weather b
a.ida.recordDatea.Temperatreb.idb.recordDateb.Temperature
42015-01-043042015-01-0430
42015-01-043032015-01-0320
42015-01-043022015-01-0225
42015-01-043012015-01-0110
32015-01-032042015-01-0430
32015-01-032032015-01-0320
32015-01-032022015-01-0225
32015-01-032012015-01-0110
22015-01-022542015-01-0430
22015-01-022532015-01-0320
22015-01-022522015-01-0225
22015-01-022512015-01-0110
12015-01-011042015-01-0430
12015-01-011032015-01-0320
12015-01-011022015-01-0225
12015-01-011012015-01-0110
Sample of the output of Query 1

Query 2

The second part of the query is where each records are tested based on the conditions specified.

 WHERE a.Temperature > b.Temperature
 AND (a.Recorddate - b.Recorddate) = 1;

Solution 3

WITH tmp AS (
SELECT id, RecordDate, Temperature,
LAG (Temperature,1) OVER (ORDER BY RecordDate) AS prev_Temperature,
LAG (RecordDate,1) OVER (ORDER BY RecordDate) AS prev_RecordDate
FROM Weather)

SELECT id FROM tmp WHERE Temperature > prev_Temperature AND
(RecordDate-prev_RecordDate)=1  

This query is very similar to my submission except that inorder to accurately test the temperature of the date vs previous date, there’s an ‘AND
(RecordDate-prev_RecordDate)=1′ condition.

Leave a comment