Hello,
I’m trying to convert a SQL query to the Ecto query, but I’m having hard time figuring out how to do that. I know I could simply execute it using SQL adapter, but I thought I might give it a try using Ecto.
The query is supposed to compare dates in historical_reports
table to all non-holiday, non-weekend dates (generated by generate_sequence
CTE and then filtered against country_holidays
table) since the first date found in the historical_reports
table. For example, assuming I have records for a whole year in my historical_reports
table and missed yesterday (non-holiday and non-weekend day), the result of executing the following query should be a single record of 2020-04-06
.
WITH company_report_date AS
(
select report_date
from historical_reports
where company_id = 1
),
year_without_weekends AS
(
SELECT date(d)
FROM generate_series((SELECT min(report_date) FROM company_report_date), current_date, interval '1 day') d
WHERE EXTRACT('ISODOW' FROM d) < 6
)
SELECT date
FROM year_without_weekends yww
WHERE yww.date NOT IN (SELECT report_date FROM company_report_date) AND
yww.date NOT IN (SELECT holiday_date FROM country_holidays) AND
yww.date <> current_date;
I started deconstructing that CTE into smaller Ecto queries, like so:
company_report_date = from hr in HistoricalReport, where: hr.company_id == ^company_id
first_date_record = from q in company_report_date, select: min(q.report_date)
At this point, I need to use a fragment to generate a sequence of dates, but I’m not sure how to proceed:
from d in fragment("select date(d) from generate_series((?), current_date, '1 day'::interval) d where extract('ISODOW' from d) < 6", first_date_record)
I guess my question is how to construct the third intermediary query when I’m not using any defined schemas / tables and then continue filtering / deconstructing it further. Also, does that approach make sense at all or should I simply use the SQL adapter and run my query as is?
Thanks!