record created longer than +90 days - sql

I have a DB which collects Work Hours Reports from workers,
and i've been asked to create an alert for a specific division
of active contracts which the last report date was bigger than 90 days
I have the ReportDate column which contains the entries and I am not sure how to create it distinct, without using the GETDATE function
as mentioned, I tried the getdate function which obviously is not valid in this case
(not code but the query needed)
select distinct (newcontractid)
where last ReportDate is bigger than 90 days...

You seem to want something like this:
select contractid
from t
where t.status = 'active' -- whatever this is
group by contractid
having max(reportdate) < current_date - interval '90 day';
This uses standard SQL syntax. In MySQL, the date functions would be:
having max(reportdate) < current_date - interval 90 day;
In SQL Server:
having max(reportdate) < dateadd(day, -90, getdate())

Related

Using a case when statement with date where a condition is within today

I have to find out whether an order is placed within 90 minutes of creation, after 90 minutes but same day and then the days after that.
I'm using a case when statement for that:
case when order <= 90 then 'within 90 minutes'
etc
What case when statement can I use for after 90 minutes but within the same day?
Assuming the column order has data type timestamp you can try the following case ...: (see demo here)
select id
, order_tm
, case when current_timestamp - order_tm < interval '90 minutes'
then 'within 90 minutes'
when current_date = order_tm::date
then 'same day, but >= 90 minutes ago'
else (extract ('day' from current_timestamp - order_tm))::text || ' days ago'
end "When Ordered"
from orders;
Note: Using order as a column name is a very poor choice. It is both a Postgres and a SQL Standard reserved word. While you can currently get away with doing so that could change in the future as it is documented and has been for quite some time. At best using a reserved word as a column name leads to confusion.

Tableau Query for using DateDiff and DateTrun at same time

I am new to tableau and i need to find all row set filter on basis of given time frame and then grouping the result of same minute.I can crack this problem in Sql as following
select count(x)
from table t
where datediff(30, min, date)
group by datepart(min, date)
How to fix it in tableau ?
I'm not really sure of what you want but this will give you the number of record per minute, for the records whose date is in the last 30 minutes:
select datepart(MI, date) , COUNT(*) as NumberOfRecordsInMinute
from table t
where date >= dateADD(MI, -30, getdate())
group by datepart(MI, date)
order by datepart(MI, date)
It isn't obvious what your SQL is trying to do here as the standard SQL datediff function works like this datediff(datepart,startdate,enddate) and returns the difference between two dates in the units specified.
If that is what you want, then the Tableau function datediff does much the same job and datediff('minute',start date,enddate) will return the number of minutes between two datetimes and it will be grouped already because the result is discrete.
You can then count the number of records matching each minute difference.

SQL : retrieve top 7 of entries added in the past week

I’m new to SQL and I need some help for a query that should return a top of occurrences sorted by date.
Actually I have a table to which are added searches done by users alongside the date of search (column is in the DATETIME format).
What I would like to do is to create a list of « Trending searches » that would show the top 7 searches done over the past week (Sunday to Sunday for example) but I’m unsure where to start.
I’ve heard of the DATEPART function but I don’t know how to use it alongside a top 7 occurrences.
Thanks in advance for your help and have a nice day !
Does this work?
declare #lastweek datetime
declare #now datetime
set #now = getdate()
set #lastweek = dateadd(day,-7,#now)
SELECT COUNT(g.searchTerm) AS appearanceCount, g.searchTerm FROM DesiredTable AS g
WHERE g.DateSearched BETWEEN #lastweek AND #now
GROUP BY(GameTypeId)
ORDER BY (appearanceCount) DESC
The mention of datepart() suggests SQL Server. If so, you can do:
select top (7) s.searchTerm, count(*)
from searches s
where s.searchTime >= dateadd(day, -7, getdate())
group by s.searchTerm
order by count(*) desc;
This gets the last 7 days to the current time.
If you want the last week, a pretty simple where is:
where datediff(week, s.searchTime, getdate()) = 1
This problem is solvable pretty easy with mysql. You are trying to do multiple things, as far as I understood:
1. Get searches from last week
With DATETIME fields there are pretty easy ways to extract the week of the year:
SELECT id FROM searches
WHERE searchDate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND searchDate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
As suggested here.
2. Get the top 7 most frequent ones
Secondly you said that you want to have the top 7 searches, which translate into most frequent occurring search terms. In other words: You need to group identical search terms together and count them:
SELECT count(id), searchTerm FROM searches
WHERE searchDate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND searchDate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
GROUP BY searchTerm
in addition:
To get the first n (here 7) rows use rownum<=7.
Like this (added to Gegenwinds solution):
SELECT result.* FROM
(SELECT count(id), searchTerm FROM searches
WHERE searchDate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND searchDate < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
GROUP BY searchTerm) result
ORDER BY count(id) DESC
WHERE rownum<= 7

SQL Date less than few days from today

I have a table in which I have emails to users and I want to make request to take users who are dated less than two days from today. How can make this?
This is my SQL table :
CREATE TABLE vacation_users(EMAIL VARCHAR(255), STARTDATE DATE, ENDDATE DATE);
The answer is this. I use HSQLDB and this is answer.
SELECT * FROM vacation_user WHERE (ENDDATE < (SYSDATE + 2 DAY));
Try this(not tested):
SELECT EMAIL from vacation_users
WHERE ENDDATE < DATEADD(day, +2, CURRENT_DATE) AND ENDDATE > CURRENT_DATE
It selects the mails, which have the enddate, which is equal bigger than current date, but smaller than current date + 2.
EDIT: I updated the answer, since the OP informed me about the DB, which is used. If CURRENT_DATE also doesn't work, you can try another from the built-in functions.
select *
from vacation_users
where STARTDATE = dateadd(day,datediff(day,2,STARTDATE),0)
That depends on a database you use, but the principle is more or less the same.
In Oracle, you'd do something like
select email
from vacation_users
where startdate < sysdate - 2;
which returns you to exact time 2 days ago (if it is 09:53 today, it'll be 09:53 2 days ago). Depending on what you really need, you might need to TRUNCate those values (so that you'd get date without its time component) or apply some other function or principle, regarding possible index impact etc.
Though, "dated less than two days from today" is ... what exactly? Is it a STARTDATE or ENDDATE (or some combination of those two)?
SELECT *
FROM vacation_users
WHERE (DATEADD(day,2,ENDDATE)) < (CONVERT(date, SYSDATETIME()))

How to pull previous month data for in January

I have an embedded query that I use to pull previous month data. Everything has been working fine until this month (January). My code looks like this:
(MONTH(CURRENT DATE)-1) = MONTH(TSTAMP)
I have it setup this way because I have a timestamp in my data that I base the query off of. This usually works like a charm, but it's not working this month and I think it's because of the new year. How does this function work when dealing with a different year? Is there a way to write it into the query so I don't have to worry about a change in year?
You can do this by using the year, like this:
YEAR(CURRENT DATE) * 12 + MONTH(CURRENT DATE) - 1 = YEAR(TSTAMP) * 12 + MONTH(TSTAMP)
This, in essence, converts the dates into months since time 0 -- so the -1 makes sense.
The proper way to do this is with a range query (one with an exclusive upper-bound, <, too), so that the db is free to us an index if one is available.
The first of the month can be retrieved pretty easily via:
CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
(Subtract the difference in days between the current date and the start of the month)
This gives a wonderful upper-bound condition for the query:
WHERE tStamp < CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
(Get everything before the start of the current month).
However, since we're really only interested in the previous month, we also need to limit the lower bound. Well that's everything since, or on, the start of that month... and since we can already get the start of the current month:
WHERE tStamp >= CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS + 1 MONTH
AND tStamp < CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
There's a related way to do this, supposing you have a calendar table with appropriate indices. If you have a minimal table with these columns:
calendarDate - DATE
year - INTEGER
month - INTEGER
dayOfMonth - INTEGER
... you can use this table to get the relevant values instead:
WHERE tStamp >= (SELECT calendarDate
FROM calendarTable
WHERE year = YEAR(CURRENT_DATE - 1 MONTH)
AND month = MONTH(CURRENT_DATE - 1 MONTH)
AND dayOfMonth = 1)
AND tStamp < (SELECT calendarDate
FROM calendarTable
WHERE year = YEAR(CURRENT_DATE)
AND month = MONTH(CURRENT_DATE)
AND dayOfMonth = 1)
(there's a couple of different forms of this, but this one looks pretty simple)