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
Related
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())
Have searched extensively through this site (and others) to try and narrow down the best way to accomplish a SQL query that will return a set of time stamped data results from yesterday within an 8 hour shift window. Couple of challenges are that this is being programmed in a proprietary (DG-LOGIK) data visualization tool that uses a JDBC connector to the SQL database so some of the standard datetime functions aren't recognized.
The query that I have successfully gotten to work is:
SELECT MAX(TimeOfSample) as TimeOfSample, SUM(SampleValue) as SampleValue FROM {trend_log}
WHERE TimeOfSample >= GETDATE()-1 AND (DATEPART(HOUR,TimeOfSample)>=07 AND DATEPART(HOUR,TimeOfSample)<=15)
GROUP BY
DATEPART(YEAR, TimeOfSample),
DATEPART(MONTH, TimeOfSample),
DATEPART(DAY, TimeOfSample),
DATEPART(HOUR,TimeOfSample),
(DATEPART(MINUTE,TImeOfSample) / 15)
ORDER BY TimeOfSample
Challenge: If you are within today's time period of the shift both today and yesterday results return. I tried limiting TimeOfSample = GETDATE()-1, but I get an error return on the equal comparison. How can I limit this query to return only yesterday?
I think this is the where clause you want:
WHERE TimeOfSample >= CAST(GETDATE()-1 as date) AND
TimeOfSample < CAST(GETDATE() as date) AND
(DATEPART(HOUR,TimeOfSample) >= 07 AND DATEPART(HOUR, TimeOfSample) <= 15)
You need to specify the lower and upper bounds of yesterday.
I have a table with two Columns Date Created and Date Modified and I need to select all of the items where the date modified is more than 5 day past the created date.
I can compare the two columns fine but have not found out how to get it to know how many days between the two.
Thanks for the help.
You can use Datediff function from SQL and specify that you want "day" as datepart.
See msdn documentation about this function.
As JamesZ stated, "day" as datepart will only check if we are past 5 days without checking if 5 days really elapsed. So I added both in the select statement. Just use the one you want.
SELECT NbDays = DATEDIFF(DAY, DateCreated, DateModified),
*
FROM [YourTable]
WHERE DATEDIFF(DAY, DateCreated, DateModified) > 5
Or
SELECT NbDaysElapsed = DATEDIFF(MILLISECOND, StartDateTime, ENDDateTime) / 86400000,
*
FROM [YourTable]
WHERE (DATEDIFF(MILLISECOND, StartDateTime, ENDDateTime) / 86400000) > 5
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)
I have this query, which output number of rows per day for the last 7 days.
How do I change it, so I only get "complete days"? meaning: results from today will not be counted (since today is not "finished").
SELECT date(downloaddate), COUNT(id) AS num_downloads,
SUM(filesize) AS daily_filesize
FROM downloads
WHERE downloaddate > now() - INTERVAL 1 WEEK
GROUP BY date(downloaddate)
Use curdate(). Unlike now() it doesn't include the time so you are effectively comparing downloaddate against today's date with time of '00:00:00' (start of day).
ie.
SELECT date(downloaddate), COUNT(id) AS num_downloads,
SUM(filesize) AS daily_filesize
FROM downloads
WHERE downloaddate < CURDATE()
AND downloaddate > CURDATE() - INTERVAL 1 WEEK
GROUP BY date(downloaddate)
You're already using date() to get the date part. Extend it's use into the where clause, or use curdate() as a shorthand for date(now()), like:
WHERE downloaddate BETWEEN curdate()
AND curdate() - INTERVAL 1 WEEK)
This will grab 7 whole days, ending last midnight.