SQL Server : get average per week for the past 30 weeks - sql

I'm trying to figure out how to get the average CHECK_AMOUNT per week for the past/last 30 weeks in SQL Server 2008.
I tried something like this (see below) but I I think that is for months and not for weeks.
SELECT TOP 30
AVG(CHECK_AMOUNT) AS W2
FROM
CHECKS
WHERE
NOT UNT='256'
GROUP BY
YEAR(DATE_GIVEN), MONTH(DATE_GIVEN)
Can anyone show me how I can make that possible please,
Thank you...

Just use a where clause comparing the dates:
select AVG(CHECK_AMOUNT)
from CHECKS
WHERE NOT UNT='256' and DATEDIFF(d, Date_Given, getdate()) <= 30*7
I'm sorry; I misread the question. You want the average per week. Your original query is quite close
select DATEDIFF(d, Date_Given, getdate())/7 as weeks_ago, AVG(CHECK_AMOUNT)
from CHECKS
WHERE NOT UNT='256' and DATEDIFF(d, Date_Given, getdate()) <= 30*7
group by DATEDIFF(d, Date_Given, getdate())/7
I'm leaving the where clause in for selecting -- rather than using top 30 -- in case there are weeks with no checks.

Can you try to add this to the group by clause ?
datepart(week, DATE_GIVEN)

Try to use Datepart
SELECT TOP 30 AVG(CHECK_AMOUNT) AS W2 FROM CHECKS WHERE NOT UNT='256' GROUP BY Datepart(week,DATE_GIVEN)

I have run reports that cross over years and the Week has messed me up.
I use
YEAR(GETDATE()) * 100 + DATEPART(Week,GETDATE()) as my YearWeek value
Otherwise, if your data crosses over years, you'll be combining last year's week with this year's week.

Related

Calculating orders placed on the end of the month

I'm currently studying SQL Server using the book Ben-Gan, Itzik. T-SQL Fundamentals. Below is a query used to select order placed at end of the month. (I know that function EOMONTH() can also be used)
SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
WHERE orderdate = DATEADD( month, DATEDIFF( month, '18991231', orderdate), '18991231');
The author's explanation is:
This expression first calculates the difference in terms of whole
months between an anchor last day of some month (December 31, 1899, in
this case) and the specified date. Call this difference diff. By
adding diff months to the anchor date, you get the last day of the
target month.
However, I'm still a bit confused as to how it actually works. Would someone kindly explain it?
That seems like a rather arcane way to do this. What the code is doing is calculating the number of months since the last day of some month. Then, it adds this number of months to that date. Because of the rules of dateadd(), the month remains the last date.
However, I prefer a simpler method:
where day(dateadd(day, 1, orderdate)) = 1
I find this much clearer.
select DATEDIFF(MONTH, '20160131', '20160201')
give us 1 month and
SELECT DATEADD(month, 1, '20160131')
give us 2016-02-29 00:00:00.000
that's ok
I tried out the query myself and seem to have got the hang of it. here is what i wrote just in case anyone else is interested
SELECT DATEADD(month, DATEDIFF(MONTH, '20160131', '20160201'), '20160131');
result:
2016-02-29 00:00:00.000
so my interpretation is that adding one or more "month" to a particular date in which the last date of the month is 31 will always return a date in which the date is the last day of the month. if this sentence makes any sense...

SQL Server- selecting X amount of days between two dates

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

How to count number of records present in a date range between a fixed time in SQL Server?

I need to get the number of records present in my [RecordsTable] for the last 3 months.
However the catch is I need the records which are processed between 10PM and 2AM.
For example --
07/01/2015 10PM -- 07/02/2015 2AM
07/02/2015 10PM -- 07/03/2015 2AM
07/03/2015 10PM -- 07/04/2015 2AM
The below SQL gives me the records present on any particular day starting from May,2015.
But I am not able to get the timing(10PM-2AM of next day) embedded in the SQL and need some help.
SELECT CONVERT(VARCHAR(12), RecordDate, 101),count(RecordID)
FROM [RecordsTable](NOLOCK)
WHERE RecordDate > '2015-05-01'
GROUP BY CONVERT(VARCHAR(12), RecordDate, 101)
MSSQL Supports both Date and Time datatypes. You can break up your where statement to reflect both date and time conditions separately.
SELECT COUNT(Records)
FROM TABLE
WHERE CONVERT(Date,DateCol) BETWEEN 'MM/DD/YYYY' AND 'MM/DD/YYYY'
AND CONVERT(Time,DateCol) BETWEEN 'HH:MM:SS' AND 'HH:MM:SS'
Try the following:
SELECT count(1)
FROM RecordsTable
WHERE RecordDate > '2015-05-01'
AND NOT DATEPART(hour, RecordDate) BETWEEN 2 AND 21
I assume RecordDate is a datetime or datetime2 column. between 2 and 21 will return rows where the hour for RecordDate is between 2am and 9pm, inclusive. NOT between 2 and 21 will return the reverse, giving you data for 10pm, 11pm, 12pm, and 1am. This does not include any time between 2:00am and 2:59am. If you need to include events that occurred precisely at but not after 2:00am, things get a bit tricker, but similar code based on not between would apply.
To get records in the last 3 months you can use two ways -- one by month looks like this
WHERE MONTH(colname) >= MONTH(GETDATE()) -3
This will get you inclusive months but not partial months. To get partial months is a bit more tricky because you could mean (for example for today) the 9th day of 3 months ago or you could mean 90 days ago. In the first case this works
WHERE colname >= dateadd(month,-3, getdate())
and for 90 days ago
WHERE colname >= dateadd(day,-90, getdate())
To get between 10PM and 2AM use this
WHERE datepart(hour,colname) >= 22 OR datepart(hour,colname) <= 2
Use DATEPART
SELECT COUNT(1)
FROM Table1
WHERE RecordDate > '2015-05-01'
AND (DATEPART(HOUR, RecordDate) <= 2 OR DATEPART(HOUR, RecordDate) >= 22)
Try this
SELECT count(*) FROM tablename where created_at>='2015-03-17 07:15:10' and created_at<='2015-07-09 02:23:50';
You can even use between
SELECT count(*) FROM tablename where created_at between '2015-03-17 07:15:10' and '2015-07-09 02:26:50';
You can use curdate() to get today's date

SQL Date Diff disregarding Year

i want to make a select, where the users birthday(date field) is less than 30 days.
what is the best way to to do it? i tried datediff, but i don't know how to put the year aside.
Thanks
You could just use DATEPART function with dayofyear datepart value.
EDIT: honestly, there is a boundary issue in my previous answer (many thanks to Damien): e.g. 2010-12-25 and 2011-01-07 => the difference should be less then 30 days, but DATEPART(dayofyear, #date) - DATEPART(dayofyear, [Birthday]) < 30 condition would skip this record. So I added an additional contition to my answer:
DATEPART(dy, #d) - DATEPART(dy, [Birthday]) < 30 OR
(
DATEPART(mm, #d) = 12 AND
DATEPART(dy, DATEADD(m, 1, #d)) - DATEPART(dy, DATEADD(m, 1, [Birthday])) < 30
)
it adds one month to the each date in the case when the month part of the first date is December and compares the difference.
A common way is to compose a formatted date, as text, and replace the year with the current year; and parse back into a date. Apply datediff on that.
If you find out datediff returns something negative thus the birthday of this year is in the past, add 1 year, and try again. This is for the time period around New Year.
SELECT *
FROM dbo.CheckBirthDay
WHERE (CASE WHEN YEAR(BirthDay) <= YEAR(CURRENT_TIMESTAMP) THEN DATEDIFF(DD,BirthDay,CURRENT_TIMESTAMP) END < 30 )

SQL Select data by this week

Hi how do I get the data by current week?
Select * from Transaction where transactionDate ....
In SQL Server based on week of year. Please see DATEPART for ##DATEFIRST etc. for example, this is all trades since Sunday in US/UK settigs:
WHERE DATEPART(week, transactionDate) = DATEPART(week, GETDATE())
Edit:
For Access, use this DatePart and use "ww" for the part of date you want.
In answer to the comment, "week" is not a variable; it's the bit of the date you want
So:
WHERE DatePart("ww", transactionDate) = DatePart("ww", GETDATE())
In Microsoft Access
Last n days:
SELECT *
FROM Transaction
WHERE transactionDate >=Date()-7
If you have indexes and this type of difference suits, it will be faster because it is sargable
This week by week difference:
SELECT *
FROM Transaction
WHERE DateDiff("w",[transactionDate],Date())=0
BTW It is considered bad practice to use *
DateDiff: http://office.microsoft.com/en-us/access/ha012288111033.aspx
Simple but portable:
SELECT *
FROM Transaction
WHERE transactionDate >= ?
AND transactionDate <= ?
Calculate the two parameters in your server-side code to whatever definition of 'week' you need.
In IBM DB2
SELECT *
FROM Transaction
WHERE transactionDate BETWEEN CURRENT TIMESTAMP - 7 days AND CURRENT TIMESTAMP;
In Access, if you want to run a query to find records that fall in the current week, use
SELECT *
FROM table
WHERE table.DateField Between (Date()-Weekday(Date())+1) And (Date()-Weekday(Date())+7);
That runs Sunday through Saturday. Use +2 and +6 instead if you want the workweek.
mySQL (standard date stamp)
SELECT *
FROM Transaction
WHERE WEEK(NOW())=WEEK(transactionDate);
mySQL (unix timestamp stamp)
SELECT *
FROM Transaction
WHERE WEEK(NOW())=WEEK(FROM_UNIXTIME(transactionDate));
Bit of a unoptimized query. Could be a more efficient way.
Note: This isn't a rolling 7 days. Just the current week of the year.
EDIT: Sorry I didn't see the ms-access tag. ignore all of this :|