Hi Guys:
This is a general SQL question, not specifically Ingress-related. But I
know there are some experts on this list!
I have a table which has rows like:
Currency_code
Start_date
End_date
Other_data
For any given currency, I should have rows like:
CURR 20070101 20070315
CURR 20070315 20070620
CURR .....
CURR 20070723 NULL
That is, the end date of the row should match the start date of the next
row, if we view the rows in START_DATE sequence.
I need to validate that this is in fact so. I.e that there are no gaps
in coverage.
It is a (one-off)diagnostic task only - there is no need for the
solution to be elegant, it just has to work: nevertheless, elegance is a
'good thing'.
It is a given that the latest row will always have a null end_date, and
start_date will always be non-null.
My current approach is in three parts:
1. Verify that end_date> start_date for all rows, counting null as
2039-12-31 via a coalesce.
2. Create a temporary table of 'min(start_date)' for all currencies.
3. Do an exception join of all start dates against all end_dates, where
the start_date is not equal to the corresponding min(start_date) from
the temporary table, and end_date is not null.
i.e validate that the starts and ends match, excluding the first start
date and latest end_date.
This seems to work ok, but can anyone come up with a better all-SQL
solution?
Cheers
Roger
--CELKO-- - 11 Jul 2007 22:59 GMT
>> This seems to work ok, but can anyone come up with a better all-SQL solution? <<
Create a Calendar table with all the temporal data you need for the
enterprise. Make it 100 years long -- storage is cheap. This is a
general purpose tool. You need to get rid of the overlaps in your
(start_date, end_date) pairs and use the ISO half-open interval model
for the ranges. It will make life a lot easier!
SELECT DISTINCT F1.currency_code AS bad_data
FROM (SELECT cal_date
FROM Calendar
WHERE cal_date
BETWEEN (SELECT MIN(start_date)
FROM Foobar AS F2
WHERE F1.currency_code = F2.currency_code)
AND CURRENT_TIMESTAMP) AS C1(cal_date)
LEFT OUTER JOIN
Foobar AS F1
ON C1.cal_date BETWEEN F1.start_date
AND COALESCE (F1.end_date, CURRENT_TIMESTAMP)
GROUP BY F1.currency_code
HAVING COUNT(C1.cal_date) <> 1;
it would be easier if there was a single minimum start date for all
currencies. The idea is to see that each calendar date occurs once
and only once in each currency's date ranges.
This does not tell you what the missing dates are, just which currency
has a gap.
Roger Hill - 19 Jul 2007 06:23 GMT
--CELKO--
Thanks for the alternative code. We do in fact use the half-open
intervals...just cleaning up after finding bugs in some code --
Thanks again.
Roger
>>> This seems to work ok, but can anyone come up with a better all-SQL solution? <<
>>>
[quoted text clipped - 31 lines]
> Info-Ingres@kettleriverconsulting.com
> http://www.kettleriverconsulting.com/mailman/listinfo/info-ingres