I want to use BETWEEN clause in this query and don't know how to do this
SELECT * FROM record
WHERE (DATEPART(yy, register_date) = 2009
AND DATEPART(mm, register_date) = 10
AND DATEPART(dd, register_date) = 10)
This gives the records from 5 hours ago until now
SELECT * FROM record
WHERE register_date BETWEEN DATEADD(HOUR, -5, GETDATE()) AND GETDATE()
It appears this might be what you want
select * from record
where register_date between '2017-10-1' and '2017-12-31'
Do note that if you want all records from the last day you might want to add time or pick the day after as the default time is 0:00
Related
I am trying to select records from today and the same day of each week for the last 4 weeks.
Today (Tuesday)
Last Tuesday
The Tuesday before that
The Tuesday before that
I need this to be tied to current date because I am going to run this query every day so I don't want to use a between or something where I manually specify the date range.
Everything I have found or tried so far has pulled the last month of data but not the last 4 weeks of the same weekday.
select *
from table
where thedatecolumn >= DATEADD(mm, -1, GETDATE())
This works but pulls everything from the last month.
If today's date is 7/10/2019 I need
Data from 7/10/2019
Data from 7/3/2019
Data from 6/26/2019
Data from 6/19/2019
Every day I will run this query, so I need it to be dynamic based on the current date.
I believe you want to look back 21 days and then filter those dates that have the same day of week:
select * from table
where thedatecolumn >= DATEADD(DAY, -21, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, thedatecolumn) = DATEPART(WEEKDAY, GETDATE())
You Can try using a recursive cte which starts today and repeatedly substracts 7 days - so you ensure you always land on the same weekday. Following an example:
WITH cteFromToday AS(
SELECT 0 AS WeeksBack, GETDATE() AS MyDate
UNION ALL
SELECT WeeksBack + 1 AS WeeksBack, DATEADD(d, -7, MyDate) AS MyDate
FROM cteFromToday
)
SELECT TOP 5 *
FROM cteFromToday
OPTION ( MaxRecursion 0 );
This is quite simple. Substitute CURRENT_TIMESTAMP here for any given date.
SELECT CONVERT(DATE,CURRENT_TIMESTAMP) AS Today,
DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AS LastWeek ,
DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AS TwoWeeksAgo,
DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AS ThreeWeeksAgo
SO, if you want to get data for a set of ranges for one entire day with those dates:
SELECT something
WHERE
datetimecolumn >= CONVERT(DATE,CURRENT_TIMESTAMP) AND datetimecolumn < DATEADD(DAY,1, CONVERT(DATE,CURRENT_TIMESTAMP)) -- Todays range,
OR datetimecolumn >= DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)))-- LastWeek ,
OR datetimecolumn >= DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)))-- TwoWeeksAgo,
OR datetimecolumn >= DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1, DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP))) -- ThreeWeeksAgo
I'm newish to SQL so sorry if the code is a little scruffy.
Basically I am creating a count of fire engines in use on every hour, which I have done, and that bit works. So I have a count of this for the past five years. Sorted.
But now I want to run it for a specific group of incidents (about 300 of them), showing how many engines were at that incident, every hour, and how many others were in use at the same time, but somewhere else.
My basic working code (that I modified from https://stackoverflow.com/a/43337534/5880512) is as follows. It just counts all P1 and P2 mobilisations at the defined time.
DECLARE #startdate datetime = '2018-05-03 00:00:00'
DECLARE #enddate datetime = '2018-05-05 00:00:00'
;with cte as
(
select #startdate startdate
union all
select DATEADD(minute, 60, startdate)
FROM cte
WHERE DATEADD(minute, 60, startdate) < #enddate
)
select convert(varchar(20), startdate, 120) as CreationTime, (select count(*) FROM MB_MOBILISATIONS WHERE MB_SEND < startdate and MB_LEAVE > startdate And (MB_CALL_SIGN Like '%P1' Or MB_CALL_SIGN Like '%P2')) as Count
from cte
option (maxrecursion 0)
To split these up for a particular incident, I can put the incident ref into the where clause, one as = so it will give me engines at that incident, and one as <> so it gives me the rest. This bit works too.
select convert(varchar(20), startdate, 120) as CreationTime, (select count(*) FROM MB_MOBILISATIONS WHERE MB_SEND < startdate and MB_LEAVE > startdate And (MB_CALL_SIGN Like '%P1' Or MB_CALL_SIGN Like '%P2') and MB_IN_REF = 1704009991) as 'At Incident'
, select convert(varchar(20), startdate, 120) as CreationTime, (select count(*) FROM MB_MOBILISATIONS WHERE MB_SEND < startdate and MB_LEAVE > startdate And (MB_CALL_SIGN Like '%P1' Or MB_CALL_SIGN Like '%P2') and MB_IN_REF <> 1704009991) as 'Other Incident'
The bit I can't work out to do, is to make this work for multiple incidents, without having to change the incident reference manually in the where clause for all 300.
The incident references I want to use will be stored in a temporary table. Ideally, I would like it to pick an ID, set the variables #startdate and #enddate, from the start and end of that incident, then do the hourly count for the duration of that incident.
Hopefully the results would look something like this
IncidentRef DateTime At Incident Other Incident
A 2018-05-03 1:00 4 2
A 2018-05-03 2:00 7 3
A 2018-05-03 3:00 5 3
A 2018-05-03 4:00 2 4
B 2017-03-01 9:00 7 2
B 2017-03-01 10:00 8 3
B 2017-03-01 11:00 6 1
B 2017-03-01 12:00 4 2
I hope that makes sense.
Thanks :)
Use something like this to limit the scope of your search to a smaller list. I've just added and referenced another CTE with a filter. If you're looking to parameterize the list you'll need a different approach like storing those id values in another table first.
with cte as (
select #startdate startdate
union all
select dateadd(minute, 60, startdate)
from cte
where dateadd(minute, 60, startdate) < #enddate
), mobi as (
select * from MB_MOBILISATIONS
where MB_IN_REF in (<insert list here>)
)
select convert(varchar(20), startdate, 120) as CreationTime, m."Count"
from cte cross apply (
select count(*) as "Count" from mobi
where MB_SEND < startdate and MB_LEAVE > startdate and
(MB_CALL_SIGN like '%P1' or MB_CALL_SIGN like '%P2')
) m;
I went ahead and rewrote your scalar subquery but I guess that's just a personal preference.
The following query (on MSSQL) gives a correct answer to the question : how many IPs were collected on a monthly basis.
I would like to know how can I get the count per every 60 days?
select MIN(rowdate) min_rowdate,
MAX(rowdate) max_rowdate,
count(distinct IP),
DATEPART(MONTH, rowdate) month_
from t_tbl tl (nolock)
where rowdate between '2015-01-01 00:00:00' and '2015-12-31 23:59:59'
group by DATEPART(MONTH, rowdate)
You can get it using DATEDIFF and some simple maths:
select MIN(rowdate) min_rowdate, MAX(rowdate) max_rowdate, count(distinct IP),
DATEDIFF(day, 0, rowdate) / 60 as day60
from t_tbl tl (nolock)
where rowdate >= '20150101' and rowdate < '20160101'
group by DATEDIFF(day, 0, rowdate) / 60
In this instance, it's using 1900-01-01 (what 0 gets converted to) as the start of the first 60 day period and all subsequent periods follow on from there.
If you want to use a different "fixed point" for the reporting periods, you'd put that in in place of 0 as the second parameter to DATEDIFF.
(I've also corrected your WHERE clause so that it doesn't exclude any events that happened during the last second of 2015, i.e. with a non-zero milliseconds value)
I have a SQL SERVER Table which has only one field "StartDate" the records are as follows
**
2011-07-28 19:30:00.000
2011-07-29 21:50:00.000
2011-07-25 09:20:00.000
**
What i want to do is :
SHOW RECORDS if its CURRENT DATE ( todays date ) and the time difference between current time the StartDate is not less then 5 minutes, i have written the following code but it doesnt show me the time difference ?
SELECT * FROM table WHERE DATEDIFF(day, StartDate, GETDATE()) <= 0
SELECT StartDate
FROM table
WHERE YEAR(StartDate)=YEAR(GETDATE())
AND MONTH(StartDate)=MONTH(GETDATE())
AND DAY(StartDate)=DAY(GETDATE())
AND (DATEDIFF(minute, StartDate, GETDATE()) >= 5
OR
DATEDIFF(minute, StartDate, GETDATE()) <= 5)
How about:
SELECT StartDate
,GETDATE()
,DATEDIFF(day, StartDate, GETDATE())
,DATEDIFF(minute, StartDate, GETDATE())
,*
FROM table
WHERE DATEDIFF(day, StartDate, GETDATE()) <= 0
AND DATEDIFF(minute, StartDate, GETDATE()) >= 5
There are two ways to do it one being DateDiff the other is DATEADD. Judging by the way I read your question DateAdd should do it. Here is an example;
SELECT *
FROM [dbo].[TABLE]
WHERE [LAST_UPDATE] > DATEADD(minute,-5,GetDate())
Using BETWEEN is probably a little more optimal than two AND statements (maybe not). Try not to do a calculation on each row if you don't have to. Doing DATEADD only on the current date will only be calculated once.
SELECT
whatever
FROM
table
WHERE
StartDate
BETWEEN FLOOR( CAST( GETDATE() AS FLOAT ) )
AND DATEADD(minute, -5, GETDATE())
I interpret the question as looking for rows where the date is today (between the start of today) but not within the last 5 minutes (and less than 5 minutes ago). That might not be what you were going for.
Hope that helps
I have a table with timestamps. What is the proper query to get the records counts for each minute for the last hour.
I.e. if now is 2:25, I want to know how many record were between 1:25 and 1:26, 1:26 and 1:27, and so on, so I have 60 results.
This will return a count of results for each minute (where you have records) in the last hour
SELECT DATEPART(n, time_stamp) AS minute, COUNT(*) as results
FROM table_name
WHERE time_stamp > DATEADD(hh, -1, GETDATE())
GROUP BY DATEPART(n, time_stamp)
This may return less than 60 results, depending on the data. If you have to have 60 results, the query is slightly different. This uses a Common Table Expression to generate a list of 60 numbers and a correlated sub-query to get the results for each minute:
WITH numbers ( num ) AS (
SELECT 1 UNION ALL
SELECT 1 + num FROM numbers WHERE num < 60 )
SELECT num AS minute,
(SELECT COUNT(*) AS results
FROM table_name
WHERE DATEPART(n, time_stamp) = num
AND time_stamp > DATEADD(hh, -1, GETDATE())
FROM numbers
To see the results, replace DATEADD(hh, -1, GETDATE()) with DATEADD(mi, -15, GETDATE()) and you'll get the results for the last 15 minutes and 0 for other minutes.
This is an alternative I have found useful for determining how many records are inserted or updated per minute. The nice thing about having your date format as a variable up front is that you can easily change it to analyze per hour instead. Hope this helps!
DECLARE #dateFormat as varchar(max) = 'yyyy-MM-dd HH:mm'
SELECT format(timeColumn, #dateFormat) AS minute, COUNT(*) as results
FROM yourTable
WHERE timeColumn > DATEADD(hh, -1, GETDATE())
GROUP BY format(timeColumn, #dateFormat)
ORDER BY 1
As you edited the question, I edit my answer. If I have understood you correctly, you want to look only at the past hour - that is, a timespan from one hour before the request is made to the current time. This is how I'd do it:
SELECT
COUNT(yourTimeStamp)
FROM yourTable
WHERE DATEADD('hh', -1, GetDate()) <= yourTimeStamp
AND yourTimeStamp < GetDate()
GROUP BY DATEPART('mm', yourTimeStamp)
I am not entirely sure that the syntax is exact. When coding in MSSQL, I would use the CURRENT_TIMESTAMP for the current time, MINUTE instead of DATEPART etc, but you get the idea for the solution.
DATEPART is what you're looking for:
declare #times table
(
someTime datetime
)
INSERT INTO #Times (sometime) values ('jan 12 2008 12:23')
INSERT INTO #Times (sometime) values ('jan 12 2008 12:34')
INSERT INTO #Times (sometime) values ('jan 12 2008 12:35')
INSERT INTO #Times (sometime) values ('jan 12 2008 12:25')
INSERT INTO #Times (sometime) values ('jan 12 2008 12:02')
INSERT INTO #Times (sometime) values ('jan 12 2008 12:09')
INSERT INTO #Times (sometime) values ('jan 12 2008 12:35')
select DATEPART(mi,sometime) AS Minute, count(*) AS NumOccurances
from #Times
WHERE SomeTime BETWEEN #Lower AND #Upper
GROUP BY DATEPART(mi, sometime)
order by NumOccurances DESC
Result:
Minute NumOccurances
35 2
2 1
9 1
23 1
25 1
34 1
If you want to group results by minute, then you can use a formatted string. This will group by number of minutes since 1/1/1900 not minute within day.
WITH formatted AS (
SELECT FORMAT(<your_datetime_column>, 'yyyy-MM-dd HH:mm') AS minute_text
FROM <your_table>
)
SELECT minute_text, COUNT(*) AS number_of_rows
FROM formatted
GROUP BY minute_text
ORDER BY 1 DESC
Here's my fixed up version of Robin's answer. I made it output the errors in the correct order and output the time as well instead of just the number which isn't super useful if you're charting this out.
WITH numbers ( num ) AS (
SELECT 1 UNION ALL
SELECT 1 + num FROM numbers WHERE num < 60 )
SELECT (SELECT DATEADD(n, -num, GETDATE())) AS TimeStamp,
(SELECT COUNT(*) AS results
FROM ErrorLogs
WHERE DATEPART(n, TimeStamp) = DATEPART(n, DATEADD(n, -num, GETDATE()))
AND TimeStamp > DATEADD(hh, -1, GETDATE())) as Count
FROM numbers
SELECT COUNT (TS) from TABLE where TABLE.TS BETWEEN(starttime, endtime)