Slow Query when using multiple between - sql

I'm including a new option on an already working query/report on business objects.
Basically it already gets the records that were created from the first of last month and today dates.
I want to add the records from the previous year's same dates (last month and previous year and today previous year).
When I introduced the OR operator to include a new between date the report that usually takes 2 minutes, won't run in less than 30 minutes.
This Works great:
Select
value1
creation
From
Table
Where
creation BETWEEN trunc((trunc(sysdate,'mm')-1),'mm') AND trunc(sysdate)
This takes more than 30 min:
Select
value1
creation
From
Table
Where
(creation BETWEEN add_months(trunc((trunc(sysdate,'mm')-1),'mm'),-12) AND add_months(trunc(sysdate),-12)
OR creation BETWEEN trunc((trunc(sysdate,'mm')-1),'mm') AND trunc(sysdate))

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.

SQL date time Query

Need help to get the data of particular format
We have a table which have a data which of production now we need to select the data of each day with particular time period which is differentiate between three shift A,B,C.
In our table we have a datetime column which capture's each seconds data now that data we need in shiftwise like 6am to 2pm is of A shift production count and 2pm to 10pm of shift B and 10pm to 6 am of shift C.
here i am getting the data for single day where i have written the below query which is working good.
select distinct(count(PRD_SERIAL_NUMBER)),(select convert(date,getdate())) as date,'B' as shift_name
from table_name
where status=02
and LAST_UPDATED_DATE
between (SELECT FORMAT(GETDATE(),'yyyy-MM-dd 14:01:00.000')) and
(SELECT FORMAT(GETDATE()-26,'yyyy-MM-dd 22:01:00.000'))
refer below output image 1
Here i am getting the count for single day and for upcoming days i have solution but now the question arise is i have a past 4 Month data which i need to get in datewise and shiftwise count and for the column prd_serial_number have duplicate entries so it should be in distinct.
please refer below image 2 for required output format

Is there a query that can add only business days , I used Date Add function but its still counting weekends?

I'm setting up web-page to display Date for scheduling. Currently I'm using Date-add to add 5 business days, using Week , but it still takes into consideration of the weekend.
I've tried the following code below and it includes weekend
select convert(varchar,dateadd(dw,5,getdate()),101)
I'm expecting it to show 5 days from today not counting the weekend.

SQL- Last 4 weeks with date column

USERS
ID TIMEMODIFIED
1 1400481271
2 1400481489
3 1400486453
4 1400486525
5 1401777484
I have timemodified field, From timemodified, I need to get the rows of last 4 weeks by taking from today's date.
SELECT id FROM USERS
WHERE FROM_UNIXTIME(timemodified,'%d-%m-%Y') >= curdate()
AND FROM_UNIXTIME(timemodified,'%d-%m-%Y') < curdate()-1
Your times are already in Unix timestamp format. Bear in mind that it'll be far more efficient to compare [TIMEMODIFIED] against the current date converted to a Unix timestamp. In addition, you don't need to check any upper bound unless [TIMEMODIFIED] can be in the future.
Try:
-- 60x60x24x7x4 = 2419200 seconds in four weeks
SET #unix_four_weeks_ago = UNIX_TIMESTAMP(curdate()) - 2419200;
SELECT id FROM USERS
WHERE timemodified >= #unix_four_weeks_ago;
NB. Four weeks ago (i.e. today – 28 days) was 1,437,696,000 (24th July) at the time of this answer. The latest record in the sample you provided has a timestamp going back to the 3rd June 2014, and so none of these records will be returned by the query.

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.