capture records 6 months prior to current month - sql

I'm working off a query where the dates are declared as integers, it's meant for a revenue report that captures the last 6 months back from x month/year. So user inputs say 10 (oct), 2014. What I want is for it to go 6 months back (10-6) and show all of the records in this range. I would think it would be something like csr.csrdatepulled >= dateadd(mm,-6.#month) -- however I don't think this works since they're integers. Right now it will just capture that month, but not the in-between. Is there a way to accomplish this with month and year declared as ints? Thanks in advance, this is a slimmed down query-
declare
#Month int,
#Year int
Set #Month = 10
Set #Year = 2014
select csr.csrdatepulled
from CustomServicesForRevenue csr
where DatePart(MM,csr.CsrDatePulled) = #Month and DatePart(yyyy,csr.CsrDatePulled) = #Year
order by csr.CsrDAtepulled desc

Construct a complete date (the 1st of the month & year) deducting 6 months and fetch rows that are >= to it
WHERE
csr.CsrDatePulled >= DATEADD(MONTH, #MONTH - 1 - 6, DATEADD(YEAR, #YEAR - 1900, 0))

Related

How to get database values by week

I just want to ask how can I achieve getting the records in a database by week in a month? using sql
What I really mean is when I input 1 it will get the records in 1st week of a month
I've done a lot of research today but it seems I can't find a good solution
Heres the code:
DECLARE #MONTH int
DECLARE #YEAR int
DECLARE #WEEK int
SET #MONTH = 9
SET #YEAR = 2013
SET #WEEK = 1
SELECT RH.RepairOrderNumber FROM dbo.RepairOrderHeader RH
WHERE MONTH(RH.DateReleased) = #MONTH AND YEAR(RH.DateReleased) = #YEAR AND WEEK(RH.DateReleased) = #WEEK
I just want to fetched the records according to month,year, and by week is there any way and precise code on how to do this?
DATEPART(WEEK,) gives you number of a week in an YEAR so you just need to calculate number of week in the month calculating difference between current date week number and the week number of the first day of the month:
WHERE MONTH(RH.DateReleased) = #MONTH
AND YEAR(RH.DateReleased) = #YEAR
AND DATEPART(WEEK,RH.DateReleased)
-DATEPART(WEEK,DATEADD(DAY,-DAY(RH.DateReleased)+1,RH.DateReleased))+1
= #WEEK
WEEK returns the week of the year, starting on a constant day of the week (i.e. each Sunday). You seem to want the week of the month, which I guess would always start on the 1st of each month.
so:
SELECT RH.RepairOrderNumber FROM dbo.RepairOrderHeader RH
WHERE MONTH(RH.DateReleased) = #MONTH AND
YEAR(RH.DateReleased) = #YEAR AND
DAY(RH.DateReleased) / 7 + 1 = #WEEK
Where possible avoid using functions on columns in the WHERE clause. You immediately lose the ability to take advantage of indices on these columns. The below solution gives the same results as the select answer, but performs much better:
DECLARE #MONTH INT = 9
DECLARE #YEAR INT = 2013
DECLARE #WEEK INT = 2
--1ST OF THE MONTH DECLARED
DECLARE #Date DATE = CAST(CAST(#Year AS VARCHAR(4)) +
RIGHT('0' + CAST(#Month AS VARCHAR(2)), 2) + '01' AS DATE)
SET #Date = DATEADD(WEEK, #Week - 1, DATEADD(DAY, 1 - DATEPART(WEEKDAY, #Date), #Date));
SELECT RH.RepairOrderNumber
FROM dbo.RepairOrderHeader RH
WHERE RH.DateReleased >= #Date
AND RH.DateReleased < DATEADD(WEEK, 1, #Date);
All this does is get the first of the month in question, then find the first day of the week that the first of the month falls in. Then adds the declared number of weeks to this date.
With an example table with 6 years of data in and 10 rows for each day (20,480 records, so not a lot) and an index on your date column the execution plans of this and the accepted answer are as follows (Accepted on top, using dates on the bottom):
Testing DDL and queries on SQL-Fiddle
This shows that when you use WEEK(DateColumn) = #Week that the index is not used at all, and the query cost is much higher. Depending on the distribution of data in your table this could make a massive difference, even in the small set of data in my example it is 800% more efficient.
I consider '2013-08-26' - '2013-09-01' the first week in september
DECLARE #MONTH int = 9
DECLARE #YEAR int = 2013
DECLARE #WEEK int = 1
DECLARE #from date= dateadd(day, datediff(day, -(#WEEK - 1)*7,
(dateadd(month, (#year-1900) * 12 + #month - 1 , 0)))/7*7 , 0)
SELECT RH.RepairOrderNumber
FROM dbo.RepairOrderHeader RH
WHERE RH.DateReleased >= #from
and RH.DateReleased < dateadd(week, 1, #from)

calculating working hours in a month

I am working on an attendance software in asp.net, in it i have to make a report which will tell the user about the hours and everything...so far i have created the basic functionality of the system, i.e. the user can check in and check out...i am stuck at making the report...
I have to calculate the working hours for every month, so the user can compare his hours with the total hours...what i had in mind was to create a stored procedure which when given a month name and a year, returns an int containing working hours for that month....but i can seem to get at it....
so far i found out how to create a date from a given month and a date, and found out the last day of that month, using which i can find out the total days in month...now i cant seem to figure out how do i know how much days to subtract for getting the working days.
here's the so far code..
declare
#y int,
#m int,
#d int,
#date datetime
set #y = 2012
set #m = 01
set #d = 01
----To create the date first
select #date = dateadd(mm,(#y-1900)* 12 + #m - 1,0) + (#d-1)
----Last Day of that date
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#date)+1,0))
any help will be appreciated guys, thanks in advance....
The #theDate is any date on the month you want to calculate the work days. This approach does not take care about holidays.
DECLARE #theDate DATETIME = GETDATE()
SELECT MONTH(#theDate) [Month], 20 + COUNT(*) WorkDays
FROM (
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, #theDate), 28) AS theDate
UNION
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, #theDate), 29)
UNION
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, #theDate), 30)
) AS d
WHERE DATEPART(DAY, theDate) > 28
AND DATEDIFF(DAY, 0, theDate) % 7 < 5
Here you can consider the below sql server code to get the first and
last day of the given month and also ignore all the Saturdays and Sundays.
DECLARE #curr_date datetime=getdate()
DECLARE #st_date datetime,#ed_date datetime
select #st_date=DATEADD(mm,datediff(mm,0,#curr_date),0),#ed_date = DATEADD(mm,datediff(mm,-1,#curr_date),-1)
--select #st_date as first_day,#ed_date as last_day
SET DATEFIRST 1 --Monday as first day of week
select DATEADD(dd,number,#st_date) from master..spt_values
where DATEDIFF(dd,DATEADD(dd,number,#st_date),#ed_date) >= 0 and type='P'
and DATEPART(DW,DATEADD(dd,number,#st_date)) <> 6
and DATEPART(DW,DATEADD(dd,number,#st_date)) <> 7
But inorder to calculate the actual working hours, you will have to take into the consideration of following thigs
1.Calculate the time interval between swipe-in and swipe-outs between start and end time for a day.
2.Exclude all the time gap(employee not in office)
3.Consider the company holidays.
etc
Here is a UDF to count work days. You can pass any date of a month to this function. But usually you should use actual "calendar" table to calculate work days and insert in this table weekends, holidays,... and so on.
CREATE FUNCTION dbo.WorkDaysCount (#Date datetime)
RETURNS int AS
BEGIN
DECLARE #BeginOfMonth datetime
SET #BeginOfMonth=DATEADD(DAY,-DAY(#Date)+1,#Date);
DECLARE #EndOfMonth datetime
SET #EndOfMonth=DATEADD(Day,-1,DATEADD(Month,1,#BeginOfMonth));
DECLARE #cDate datetime
set #cDate=#BeginOfMonth
Declare #WorkDaysCount int
SET #WorkDaysCount=0
while #cDate<=#EndOfMonth
begin
if DATEPART(dw,#cDate) not in (1,7) SET #WorkDaysCount=#WorkDaysCount+1 -- not a Sunday or Saturday change (1,7) to (6,7) if you have other week start day (Monday).
set #cDate=#cDate+1;
end;
return (#WorkDaysCount);
END

(sql server 2005) How to determine the WEEK number starting from GETDATE() [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Getting week number off a date in MS SQL Server 2005?
Please suppose (i am in Italy) that all the weeks start with Monday and end with Sunday.
I would like to write a scalar valued function that determines the number of the week with reference to GETDATE()
Thank you in advance for your kind cooperation.
PLEASE PAY ATTENTION TO THIS: The SELECT has to be INDIPENDENT from the SET DATEFIRST command!!
Can you use the two liner?
SET DATEFIRST 1;
SELECT DATEPART( WEEK , GETDATE())
for today
SELECT DATEPART( WEEK , GETDATE())
returns 30 whereas
SET DATEFIRST 1;
SELECT DATEPART( WEEK , GETDATE())
returns 31
Edit Untested but based on This Question you can get the equivalent of the SQL Server 2008 datepart(iso_week, getdate()) (which i believe is what you want) with the following select statement
SELECT ISOWeek = (DATEPART(DY, Th) - 1) / 7 + 1
FROM (SELECT Th = DATEADD(D, 3 - (DATEPART(DW, getdate()) + ##DATEFIRST - 2) % 7, getdate())) s
Here's a little snippet that should do what you need.
DECLARE #firstOfYear DATETIME
SET #firstOfYear = STR(Year(GETDATE()), 4)+'-01-01 00:00:00'
SELECT DATEDIFF(ww, #firstOfYear - ((DATEPART(dw, #firstOfYear) + 5) % 7), GETDATE())
Keep in mind that if you want to set the week start to on a different day, just change the +5 to the value based on 7 - dw. This is for MSSQL.
This works by getting the first day of the year and finding the day of the starting week on or before that day. Then we get the number of weeks between whatever date was passed in and that "first" week start. If you want to allow any date to be passed in, just replace all GETDATE calls with your parameter and you should be good to go. If you need a single select statement:
SELECT
DATEDIFF(ww, day1 - ((DATEPART(dw, day1) +5) % 7), GETDATE())
FROM
(SELECT CAST(STR(Year(GETDATE()), 4)+'-01-01 00:00:00' AS DATETIME) day1) d
select datepart(week,getdate())
more at http://msdn.microsoft.com/en-us/library/aa258265(v=sql.80).aspx
declare #oldDF int
set #oldDF = ##DATEFIRST
set DATEFIRST 1
select DATEPART(WEEK, GETDATE())
set DATEFIRST #oldDF

SQL create a DateTime value from Year and Quarter

I know the year and the quarter (e.g. "2010" and "4") for a schedule-related milestone and I want to select/create a datetime from it. There are a number of nifty ways to identify the quarter with formats ("qq") of a particular date, but not to go the other way around (or are there?). This is with t-sql / SQL Server.
Note: the datetime should be for the last day of that quarter.
UPDATE: Here is the solution that I ended up using courtesy of gbn, with AaronLS's variable names and then shortened-and-sweetened with Frank Kalis' suggestion :-) It was important to test for all 4 quarters to make sure the year is handled properly. Thanks to everyone who answered!
DECLARE #TheQuarter INT
DECLARE #theYear INT
-- Note: qq = q = quarter for the datepart
SET #TheQuarter = 1
SET #TheYear = 2011
SELECT DATEADD(YEAR, #TheYear-1900, DATEADD(qq, #TheQuarter, -1))
-- 2011-03-31 00:00:00.000
SET #TheQuarter = 2
SET #TheYear = 2011
SELECT DATEADD(YEAR, #TheYear-1900, DATEADD(qq, #TheQuarter, -1))
-- 2011-06-30 00:00:00.000
SET #TheQuarter = 3
SET #TheYear = 2011
SELECT DATEADD(YEAR, #TheYear-1900, DATEADD(qq, #TheQuarter, -1))
-- 2011-09-30 00:00:00.000
SET #TheQuarter = 4
SET #TheYear = 2011
SELECT DATEADD(YEAR, #TheYear-1900, DATEADD(qq, #TheQuarter, -1))
-- 2011-12-31 00:00:00.000
Here are a few q's that fetch the quarter from the date but not the other way around:
Calculate the Last Day in the CURRENT quarter; Calculate the last day of the quarter; Best way to store quarter and year in SQL Server?
Never use strings for datetime conversions: too much to go wrong with formats, language etc.
Keep it in the datetime type...
Select dateadd(day, -1,
dateadd(year, #year-1900,
dateadd(quarter, #qq, 0)
)
)
Looks like you've already found your solution, but just for the sake of it...
If you choose a different base date, you can shorten the whole thing to
SELECT DATEADD(YEAR, #TheYear-1900, DATEADD(qq, #TheQuarter, -1))
Since 0 indicates SQL Server's base date of 01.01.1900 (and the first day of a month), using -1 as base date starts off 1 day earlier and then you already have your last day of a month (and end of a quarter). Then you just need to do the rest of the datetime magic and voilĂ .
Just choose the date from the quarter:
select
case #theQuarter
when 1 then '3/31/' + cast(#theYear as varchar(4))
when 2 then '6/30/' + cast(#theYear as varchar(4))
when 3 then '9/30/' + cast(#theYear as varchar(4))
when 4 then '12/31/' + cast(#theYear as varchar(4))
end as quarterDate
Edit: Adjusted to be last day of quarter instead of first day.
This basically gets the first day of the following quarter, and then subtracts one so that you have the last day of the quarter you wanted. (#theQuarter + 1) adds one to the quarter, then *3 -2 gets the first month of that quarter, and % 12 is required when for the fourth quarter because you add one to 4 to get 5, which gives you 13 but you really want 1, so the % takes care of that.
Finally after casting it all to a date time, we have the first day of the following quarter, thus subtract - 1 at the end to subtract one day and get the last day of the quarter we initially put in.
declare #theQuarter as int;
set #theQuarter = 4;
declare #theYear as int;
set #theYear = 2009;
select
cast(
cast(
( (#theQuarter + 1) * 3 - 2) % 12
as varchar(2))
+ '-01-'
+ cast( (#theYear + (((#theQuarter + 1) * 3 - 2)/ 12) ) as varchar(4))
as datetime) - 1 ;

How to write select query for this?

I have column COMPONENT_AMOUNT(money) ,MONTH_FOR(int), YEAR_FOR(int) and COMPONENT_TYPE(int). I want to find the sum of amount according to condition. I have written my query like this but it solve my purpose.
My purpose is that if one select Nov-2010 then it will sum the amount up to this selected month including all the month of 2009.
My query is given below ,please modify it:
SELECT SUM(Convert(Numeric(7,2), Round([COMPONENT_AMOUNT],2,1)))
FROM [TEAM_FUNDS_DETAILS]
WHERE YEAR_FOR <= 1 AND MONTH_FOR <= 1 AND [COMPONENT_TYPE] = 1
If You need only one result per query I think that this is code
declare #year int
declare #month int
set #year = 2010 --desire year
set #month = 8 --desire month
select sum(COMPONENT_AMOUNT)
from [TEAM_FUNDS_DETAILS]
WHERE
[COMPONENT_TYPE] = 1
and (
YEAR_FOR < #year
or (year_for=#year and month_for<=#month)
)