How to calculate a birthday date regardeless of year - sql

I would like to calculate customer with the account creation date in the next 8 days, so i want to calculate this date using only the day and the month , if the creation anniversary date is in 8 days, i can retrieves these contacts and contact them.
is there any exemple of query using only month an day to calculate the upcoming date?
thank you

You can try doing something like this (tested on PostgresQL, may require some adjustments for other DBs):
select * from temp_contacts where
to_char(date_created, 'MM-dd') =
to_char(current_date + interval '8 day', 'MM-dd');
For each row it first maps the date_created to a string using MM-dd format, then does the same to the current date + 8 days and compares the two.
This of course is not using any index, so it will not perform well on a table with large enough size.
Some DBs support creating function based indices. For example PostgresQL or Oracle DB. In MySQL you can achieve the same by creating an auto generated column and indexing on it.

Related

Calculate the average time between two dates

I need to find the result of a calculation that is nothing more than the average time in days from creation to completion of a task.
In this case, using a Redshift database (looker).
I have two dates (2022/10/01 to 2022/10/21) and I need to find the average day of execution of the creation of an object from start to finish.
Previously, I was able to calculate the totals of objects created per day, but I can't bring up the average:
SELECT created::date, count(n1pk_package_id)
FROM dbt_dw.base_package
WHERE fk_company_id = 245821 and created >= '2022-10-01' and created < '2022-10-22'
GROUP BY created::date
ORDER BY created DESC
I'm not able to do the opposite way of the count to bring the average of the range of days.
Assumption:
There is a created column in your table
You want to know the 'average' of the created column
You could extract the number of days that each date is different from a base date, and then use that to determine the 'average date'. It would be something like this:
select
date '2022-10-01' + interval '1 day' * int(avg(created - date '2022-10-01'))
from table
It subtracts a date (any date will do) from created, finds the average of that value against all desired rows, converts it to days and adds it back to that same date.

Big query sql: month to date query

I have daily data and the code im using creates a report between some dates. I want to replace the date interval with month to date. So every time it will generate a month to date report based on which month we are in. Is there a simple way to do it? thanks :)
An example using BigQuery Standard SQL
SELECT
*
FROM
your_table
WHERE
your_date_field BETWEEN
DATE_TRUNC(CURRENT_DATE(), month) --to get start date of current month
AND
CURRENT_DATE()
You should be able to use that in a WHERE clause and

How to round up a month-date based on certain parameters

I need to round up a month-date based on certain parameters. For example: If I have a parameter where if a day in a given month is between the 6th and the 4th of the next month, I need my query to return the next months date. Is there a way to round up the month given these parameters without hard coding case whens for every single month ever?
SELECT case when date_trunc('day',li.created_at between '2019-03-06 00:00:00' and '2019-04-06 00:00:00' then '2019-04-01' end)
FROM line_items li
If you want the beginning of the month, but offset by 4 days, you can use date_trunc() and subtract some number of days (or add some number of days). You seem to want something like this:
select dateadd(month, 1, date_trunc('month', li.created_at - interval '4 day'))
Another approach is to create a canonical "dates" table that precomputes the mapping from a given date to a new date using your rounding scheme. The mapping could be done outside of redshift in a script and the table loaded in (or within redshift using a user defined function).

SQL query to search by day/month/year/day&month/day&year etc

I have a PostgreSQL database with events. Each event has a datetime or an interval. Common data are stored in the events table and dates are stored in either events_dates (datetime field) or events_intervals (starts_date, ends_date both are date fields).
Sample datetime events
I was born on 1930-06-09
I got my driver's license on 1950-07-12
Christmas is on 1900-12-24 (1900 is reserved for yearly reoccuring events)
Sample interval events
I'll be on vacation from 2011-06-09 till 2011-07-23
Now I have a user that will want to look up these events. They will be able to fill out a form with from and to fields and in those fields they can enter full date, day, month, year, day and month, day and year, month and year in one or both fields.
Sample queries
From May 3 to 2012 December 21 will look for events between May 3 and December 21 whose max year is 2012
From day 3 to day 15 will look for events between the 3rd and 15th day of every month and year
From day 3 will look for events on the 3rd day of every month and year (same if from is empty and to is not)
From May 3 to June will look for events between May 3 and last day of June of every year
etc.
Any tips on how to write a maintanable query (it doesn't necessarily have to be fast)?
Some things that we thought of
write all possible from, to and day/month/year combinations - not maintable
compare dates as strings e.g. input: ____-06-__ where _ is a wildcard - I wouldn't have to generate all possible combinations but this doesn't work for intervals
You can write maintainable queries that additionally are fast by using the pg/temporal extension:
https://github.com/jeff-davis/PostgreSQL-Temporal
create index on events using gist(period(start_date, end_date));
select *
from events
where period(start_date, end_date) #> :date;
select *
from events
where period(start_date, end_date) && period(:start, :end);
You can even use it to disallow overlaps as a table constraint:
alter table events
add constraint overlap_excl
exclude using gist(period(start_date, end_date) WITH &&);
write all possible from, to and day/month/year combinations - not maintable
It's actually more maintainable than you might think, e.g.:
select *
from events
join generate_series(:start_date, :end_date, :interval) as datetime
on start_date <= datetime and datetime < end_date;
But it's much better to use the above-mentioned period type.

SQL queries with date types

I am wanting to do some queries on a sales table and a purchases table, things like showing the total costs, or total sales of a particular item etc.
Both of these tables also have a date field, which stores dates in sortable format(just the default I suppose?)
I am wondering how I would do things with this date field as part of my query to use date ranges such as:
The last year, from any given date of the year
The last 30 days, from any given day
To show set months, such as January, Febuary etc.
Are these types of queries possible just using a DATE field, or would it be easier to store months and years as separate tex fields?
If a given DATE field MY_DATE, you can perform those 3 operation using various date functions:
1. Select last years records
SELECT * FROM MY_TABLE
WHERE YEAR(my_date) = YEAR(CURDATE()) - 1
2. Last 30 Days
SELECT * FROM MY_TABLE
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) < MY_DATE
3. Show the month name
SELECT MONTHNAME(MY_DATE), * FROM MY_TABLE
I have always found it advantageous to store dates as Unix timestamps. They're extremely easy to sort by and query by range, and MySQL has built-in features that help (like UNIX_TIMESTAMP() and FROM_UNIXTIME()).
You can store them in INT(11) columns; when you program with them you learn quickly that a day is 86400 seconds, and you can get more complex ranges by multiplying that by a number of days (e.g. a month is close enough to 86400 * 30, and programming languages usually have excellent facilities for converting to and from them built into standard libraries).