how to get last week count using sql statement? - sql

I'm trying to write a sql query to get last week's count in the format of mm/count/yyyy. In my situation, Wednesday starts a new week. So today March 8th, 2012 is the second week of March, and the last week count is 03/01/2012. Please note, the 01 means week count not date. If consider March 1st, 2012, the last week count should be the last week of Feburary which is 02/05/2012
Update: Thanks for Steve's comment, reminding me to clear my question here. Each month starts from it's first Wednesday. So the 03/01/2012 starts from March 7th, 2012 to March 13th, 2012
Any sql query solution?
I'm using sql-server

Here's some date logic to get you started. I can't comprehend your funky "last week count" definition by the two examples, so I can't code it.
DECLARE
#Now datetime,
#Today datetime,
#MonthStart datetime,
#WeekCount int,
#Result varchar(10)
SET #Now = GetDate()
SET #Today = DateAdd(dd, DateDiff(dd, 0, #Now), 0)
SET #MonthStart = DateAdd(mm, DateDiff(mm, 0, #Today), 0)
-- relative to the actual day the month started
SET #WeekCount = ((DatePart(dd, #Today)-1) / 7) + 1
-- relative to Sunday
--SET #WeekCount = (DatePart(week, #Today) - (DatePart(week, #MonthStart) + 1
SET #Result = convert(varchar(10), #Today, 101)
SET #Result =
LEFT(#Result, 3) -- month/
+ RIGHT('z00' + convert(varchar(2), #WeekCount), 2) -- week with zero pad
+ RIGHT(#Result, 5) -- /year
SELECT
#Now as TheNow,
#Today as Today,
#MonthStart as MonthStart,
#WeekCount as WeekCount,
#Result as Result
See also SET DATEFIRST

in oracle:
select to_char( sysdate, 'w' ) from dual

#Steven,
Sorry, this didn't fit as a comment.
Your description of "[nth] week in [month]" is not clear. Your week starts on Wednesday. February first was a Wednesday, so the weeks in February, 2012, if there are indeed 5 of them, are
February 1-7
February 8-14
February 15-21
February 22-28 and
February 29 - March 6
You describe March 8 as being in the "second week of March," so the first week of March must be the previous week, which is February 29 - March 6. Note that this is also what you call "the last (fifth) week in February."
By your description, then, the weeks you write as '02/05/2012' and '03/01/2012' are the same week with different names.
What is the rule that lets you know that
You want the same "last week" when you run the program March 1 as when you run it March 8
You want that week (which is the same) described differently in these two cases.
Or does your question have a mistake in it.
Once you can describe what you need, it will be easy to program. If you don't know what you want, it will be impossible to program.

In SQL Server these queries return 1,1,2,5
select ((DATEPART(dd, 'March 01, 2012')-1)/7) + 1
select ((DATEPART(dd, 'March 07, 2012')-1)/7) + 1
select ((DATEPART(dd, 'March 08, 2012')-1)/7) + 1
select ((DATEPART(dd, 'March 31, 2012')-1)/7) + 1
So this may be what you need
declare #dt datetime = 'March 31, 2012'
select
CONVERT(nvarchar(4), DATEPART(month,#dt)) + '/' +
CONVERT(nvarchar(4), ((DATEPART(dd, #dt)-1)/7) + 1) + '/' +
CONVERT(nvarchar(4), DATEPART(year,#dt))
which produces '3/5/2012'

SELECT
RIGHT(100 + MONTH(D) , 2) + '/' +
RIGHT(100 + (DAY(D) + 6) / 7, 2) + '/' +
DATENAME(YEAR, D)
FROM (
SELECT DATEADD(WEEK, -1, GETDATE()) AS D
) s

I think that should do it, I don't get the value for last week because it was confusing and the answer is cleaner that way, you can just add a DATEADD(day,-7,date) somewhere.
SET DATEFORMAT YDM
CREATE TABLE #Dates (Date DATETIME)
INSERT INTO #Dates VALUES ('2012-31-03');
INSERT INTO #Dates VALUES ('2012-15-02');
INSERT INTO #Dates VALUES ('2012-02-04');
INSERT INTO #Dates VALUES ('2012-02-05');
WITH Mondays as (
SELECT DATEADD(week, DATEDIFF(week,0, DATEADD(day,6-DATEPART(day,d.Date),d.Date) ), 0) FirstMonday,
DATEADD(week, DATEDIFF(week,0, DATEADD(day,6-DATEPART(day,DATEADD(month, -1, d.Date)),DATEADD(month, -1, d.Date)) ), 0) FirstMondayOfLastMonth,
d.Date
FROM #Dates d),
Wednesday as (
SELECT CASE WHEN DATEPART(day,m.FirstMonday) <= 5
THEN DATEADD(day,2,m.FirstMonday)
ELSE DATEADD(day,-5,m.FirstMonday) END FirstWednesday,
CASE WHEN DATEPART(day,m.FirstMondayOfLastMonth) <= 5
THEN DATEADD(day,2,m.FirstMondayOfLastMonth)
ELSE DATEADD(day,-5,m.FirstMondayOfLastMonth) END FirstWednesdayOfLastMonth,
m.Date
FROM Mondays m)
SELECT w.Date,
CASE WHEN w.Date >= w.FirstWednesday THEN
RIGHT('0' + CAST(DATEPART(month,w.Date) AS NVARCHAR(2)),2)
+ '/0' + CAST(DATEDIFF(week,w.FirstWednesday, w.Date) + 1 AS NVARCHAR(2))
+ '/' + CAST(DATEPART(year,w.Date) AS NVARCHAR(4))
ELSE
RIGHT('0' + CAST(DATEPART(month,w.FirstWednesdayOfLastMonth) AS NVARCHAR(2)),2)
+ '/0' + CAST(DATEDIFF(week,w.FirstWednesdayOfLastMonth, w.Date) + 1 AS NVARCHAR(2))
+ '/' + CAST(DATEPART(year,w.FirstWednesdayOfLastMonth) AS NVARCHAR(4))
END AS weekDate
FROM Wednesday w
DROP TABLE #Dates
The result is :
Date weekDate
2012-03-31 00:00:00.000 03/04/2012
2012-02-15 00:00:00.000 02/03/2012
2012-04-02 00:00:00.000 03/05/2012
2012-05-02 00:00:00.000 05/01/2012

Related

How to bring India financial years base on month using SQL select query?

I need financial year as below format. in India financial year runs from 1 April to 31 March in every year.
1. Example 1 April 2018 to 31 march 2019 (2018 - 2019).
2. Example 1 April 2019 to 31 march 2020 (2019 - 2020).
I want below output and select query need below columns from 2018 to currently date, if the new April month starts then again new dropdown value should come, example 2020 year past then if current month April 2021 then the new dropdown value 2021 - 2022 should come like that so on.
Year FinancialYear
------------------------
2018 2018-2019
2019 2019-2020
this will gives you current & previous financial year. It uses Table Value Contructor to generate 2 rows
select datename(year, dateadd(month, -3, [date])) as [Year],
datename(year, dateadd(month, -3, [date]))
+ '-' +
datename(year, dateadd(month, +9, [date])) as [FinancialYear]
from (
values
(dateadd(year, -1, getdate())), -- previous fy
(getdate()) -- current financial year
) as fy ([date])
order by [date]
You can try using datefromparts() function as shown below. Here is the official documentation of DATEFROMPARTS (Transact-SQL).
This function returns a date value that maps to the specified year, month, and day values.
Syntax
DATEFROMPARTS ( year, month, day )
Below is the implementation for you.
create table FinancialYear (Year int)
insert into FinancialYear values (2018), (2019), (2020)
Select Year,
Cast(Year as Varchar(4)) + '-' + Cast(year + 1 as varchar(4)) as FinancialYear
,datefromparts(year, 4, 1) as [StartingDate]
,datefromparts(year + 1 , 3, 31) as [EndingDate]
from FinancialYear
Live Demo
The output is as shown in the below image.
There is an alternative by using cte you do not need table as shown below.
-- Define start and end limits
Declare #start int, #end int
Select #start = 2018, -- As you want
#end = year(getdate()) --Current Year
;With NumberSequence( Year ) as
(
Select #start as Year
union all
Select Year + 1
from NumberSequence
where Year < #end
)
--Select result
Select Year,
Cast(Year as Varchar(4)) + '-' + Cast(year + 1 as varchar(4)) as FinancialYear
,datefromparts(year, 4, 1) as [StartingDate]
,datefromparts(year + 1 , 3, 31) as [EndingDate]
from NumberSequence Option (MaxRecursion 1000)
Here is the Live Demo.
Edit
If you are using SQL Server 2005 then your query will be as shown below.
insert into FinancialYear values (2018)
insert into FinancialYear values (2019)
insert into FinancialYear values (2020)
Select Year,
Cast(Year as Varchar(4)) + '-' + Cast(year + 1 as varchar(4)) as FinancialYear
,CAST(Convert(Varchar(4), year) + '-' + '4' + '-' + '1' as DATETime) as [StartingDate]
,CAST(Convert(Varchar(4), year + 1) + '-' + '3' + '-' + '31' as DateTime) as [EndingDate]
from FinancialYear
If you want to exclude the financial year when month number is either Jan, Fab or March then you can write where condition for that as below.
Select Year,
Cast(Year as Varchar(4)) + '-' + Cast(year + 1 as varchar(4)) as FinancialYear
,CAST(Convert(Varchar(4), year) + '-' + '4' + '-' + '1' as DATETime) as [StartingDate]
,CAST(Convert(Varchar(4), year + 1) + '-' + '3' + '-' + '31' as DateTime) as [EndingDate]
from FinancialYear
where (
(ISNULL(month(getdate()), 0) >= 4 )
OR
(ISNULL(month(getdate()), 0) < 4 AND Year < year(getdate()))
)
I know its a bit lengthy, but it will work.
drop table if exists #asa
declare #getdate datetime='2025-04-06 00:00:00.000'
DECLARE #FromDate varchar(30),#ToDate varchar(30),#datediff2018 INT=CONVERT(INT,datediff(day,'2017-04-01',#getdate)/365.25)
create table #asa
(
Year varchar(10),
FY varchar(20)
)
WHILE(#datediff2018>0)
BEGIN
IF(MONTH(#getdate)>=4 AND MONTH(#getdate)<=12)
BEGIN
SET #FromDate=CONVERT(VARCHAR(10),YEAR(dateadd(year,-#datediff2018+1,#getdate)))+'-04-01'
END
ELSE IF(MONTH(#getdate)>=1 AND MONTH(#getdate)<=3)
BEGIN
SET #FromDate=CONVERT(VARCHAR(10),YEAR(dateadd(year,-#datediff2018+1,#getdate))-1)+'-04-01'
END
IF(MONTH(#getdate)>=4 AND MONTH(#getdate)<=12)
BEGIN
SET #ToDate=CONVERT(VARCHAR(10),YEAR(dateadd(year,-#datediff2018+1,#getdate))+1)+'-03-31'
END
ELSE IF(MONTH(#getdate)>=1 AND MONTH(#getdate)<=3)
BEGIN
SET #ToDate=CONVERT(VARCHAR(10),YEAR(dateadd(year,-#datediff2018+1,#getdate)))+'-03-31'
END
insert into #asa
select YEAR(#FromDate),CONVERT(VARCHAR,YEAR(#FromDate))+'-'+CONVERT(VARCHAR,YEAR(#ToDate))
set #datediff2018=#datediff2018-1
END
select * from #asa

SQL Server 2005 Date Range

I want to run a query on a specific date range for my company's fiscal year, which ends in October.
The query needs to run from October 1 of the last year through the current date, but if the current year gets past October, then it needs to switch over to October of this year.
So: currently it would be October 1, 2013 to July 16, 2014.
Starting on October 2, 2014 it will be October 2, 2014 to October 2, 2014.
I could simply go in and change the SQL every October, but I figured there was an easier way to do this with a logic statement.
Thanks!
Do you want something like this:
SELECT
<your_column_list>
FROM TABLE
WHERE
date_col >= CASE
WHEN MONTH(GETDATE()) < 10 THEN CAST(('1.10.' + CAST(YEAR(GETDATE()) - 1 as CHAR(4)) AS DATETIME)
ELSE GETDATE()
END
AND
date_col < CASE
WHEN MONTH(GETDATE()) < 10 THEN GETDATE()
ELSE
CAST(('1.10.' + CAST(YEAR(GETDATE()) + 1 as CHAR(4)) AS DATETIME)
END
I'm not sure about the exact dates, i don't get the october 2nd part. You will have to adjust the date format as well. I used dd.mm.yyyy on your system it might be different.
So this should be giving the desired results.
DECLARE #startDate DATETIME,
#endDate DATETIME,
#today DATETIME;
BEGIN
SET #today = CONVERT(DATETIME, '03/1/14');
SELECT #startDate = CASE
WHEN MONTH(#today) < 10 THEN '10/01/' + LTRIM(STR(YEAR(DATEADD(YEAR, -1, #today))))
WHEN MONTH(#today) = 10
AND MONTH(#today) = 1 THEN '10/01/' + LTRIM(STR(YEAR(DATEADD(YEAR, -1, #today))))
WHEN MONTH(#today) = 10
AND MONTH(#today) > 1 THEN '10/01/' + LTRIM(STR(YEAR(#today)))
WHEN MONTH(#today) > 10 THEN '10/01/' + LTRIM(STR(YEAR(#today)))
ELSE '1/1/2000'
END,
#endDate = GETDATE();
SELECT #startDate, #endDate;
END;

How can I use GETDATE() to get month and year from the past month?

How can I get it to one statement that can get me
last month and this year?
I have a INSERT INTO and in a column report_date [datetime]
insert into table_a (report_date) values ( ??);
i want to show this past month and year,
So for example today is 4/21/2014
so it would show 3/2014 in the column
If today was MAY 1 2014 , it would show 4/2014?
Is this possible or does it have to have a day?
You're looking for the DATEADD function:
SELECT DATEPART(month, DATEADD(month, -1, GETDATE()), DATEPART(year, DATEADD(month, -1, GETDATE())
If you are trying to get 'last month' with 'this year' you could do:
SELECT CAST(
CAST(YEAR(GETDATE()) AS VARCHAR) + '-' +
CAST(MONTH(GETDATE())-1 AS VARCHAR) + '-' +
CAST(DAY(GETDATE()) AS VARCHAR)
AS DATETIME)
But then in JAN 2015, it would return DEC 2015.
If you just want last month, use the 'DATEADD' function.
SELECT DATEADD(MONTH, -1, GETDATE())

SQL Server 2008 select data only between month and year

I would like select data between two date, without day
An input example:
start month: 9 , start year: 2011
end month: 3, end year: 2012
I think that there are two way to do this.
The first is convert start month and start year to date like 2011-09-01 and convert last date to 2012-03-31, but this requires calculation of the last day of end month. Obtained these date we can use a BEETWEN function for the WHERE clause (but, is the CONVERT function reliable?)
The second solution is to use the DATEPART function like in the following code:
I try to explain: if end year is equal to the initial year, then month must be between the start and end months; else if the final months is greater than the initial years if different from the initial and final year, I take everything in between; else if the final year, the month must be less than or equal to the final month, if the initial year, month must be greater than or equal to the final month
Can you help me do this in the best way? Is correct, the solution I adopted?
declare #IndDebitoCredito bit,#ProgTributo int,#mi as integer,#ai as integer,#mf as integer,#af as integer,#IDAnagrafica varchar(5)
select #mi = 01,#ai = 2011,#mf = 12,#af = 2011,#IDAnagrafica = 'DELEL',#IndDebitoCredito = 1
select distinct rrd.IDTributo
from TBWH_Delega d
--inner join TBWH_SezioneDelega sd on d.IDDelega = sd.IDDelega
inner join TBWH_Rigo rd on rd.IDDelega = d.IDDelega
inner join TBWH_RataRigo rrd on rrd.IDRigo = rd.IDRigo
where
(
DATEPART(MM,d.DataDelega)<=#mf and
DATEPART(MM,d.DataDelega)>=#mi and
DATEPART(YYYY,d.DataDelega)=#ai and
#af = #ai
)
OR
(
--anno finale magg. anno iniziale
#af > #ai AND
(
( -- delega nell'intervallo
DATEPART(YYYY,d.DataDelega)<#af AND
DATEPART(YYYY,d.DataDelega)>#ai
-- DATEPART(MM,d.DataDelega)>=#mi
)
OR
( -- delega limite destro
DATEPART(YYYY,d.DataDelega)=#af AND
DATEPART(MM,d.DataDelega)<=#mf
)
OR
( -- delega limite sinistro
DATEPART(YYYY,d.DataDelega)=#ai AND
DATEPART(MM,d.DataDelega)>=#mi
)
)
)
GO
Your first solution is almost there, but is more complicated than it needs to be and won't work anyway. It will miss out any rows from the last day of the end month.
You can add one month to the end month and then use BETWEEN on the first of each month. eg.
start month: 9 , start year: 2011
end month: 3, end year: 2012
BETWEEN '2011-09-01' AND '2012-04-01'
or, as JNK points out, this will be better:
DataDelega >= '2011-09-01' AND DataDelega < '2012-04-01'
You'll need to add in some logic to deal with the end month being December, but this looks like the simplest way of doing it.
You are WAY overcomplicating this. You really only need two comparisons:
Is the month and year after or equal to the initial value?
Is the month and year before or equal to the final value?
Try:
SELECT *
FROM MyTable
WHERE Datefield BETWEEN
CAST(#mi as varchar) + '/1/' + CAST(#ai as varchar)
-- first of first month
AND
DATEADD(DAY, -1, (DATEADD(Month, + 1, (CAST(#mf as varchar) + '/1/' + CAST(#af as varchar)))))
-- Last day or final month
SELECT *
FROM Table
WHERE DateField
BETWEEN CONVERT(DATE, CONVERT(CHAR(4), #ai) + RIGHT('00' + CONVERT(VARCHAR(2), #mi), 2) + '01', 112)
AND DATEADD(DD, -1, DATEADD(MM, 1, CONVERT(DATE, CONVERT(CHAR(4), #af) + RIGHT('00' + CONVERT(VARCHAR(2), #mf), 2) + '01', 112)))
Avoid using expressions on the DateField columns, as it makes query not SARGable.
I would use:
WHERE DateToCheck >= --- first day of StartMonth
DATEADD( mm, #StartMonth-1,
DATEADD( yy, #StartYear-2000, '2000-01-01')
)
AND DateToCheck < --- first day of next month (after EndMonth)
DATEADD( mm, #EndMonth,
DATEADD( yy, #EndYear-2000, '2000-01-01')
)
DECLARE #mi INT
, #ai INT
, #mf INT
, #af INT
SELECT #mi = 01
, #ai = 2011
, #mf = 12
, #af = 2011
--local variables to hold dates
DECLARE #i DATETIME
, #f DATETIME
--build strings to represent dates in YYYYMMDD format
--add a month to the #f date
SELECT #i = CONVERT(VARCHAR(4), #ai) + RIGHT('0' + CONVERT(VARCHAR(2), #mi),
2) + '01'
, #f = DATEADD(month, 1,
CONVERT(VARCHAR(4), #af) + RIGHT('0'
+ CONVERT(VARCHAR(2), #mf),
2) + '01')
--select data where date >= #i, and < #f
SELECT *
FROM MyTable
WHERE DateField >= #i
AND DateField < #f

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 ;