Making new column based on date with variable year - sql

As topic is saying, it all should apply to dates with variable year.
I would like to make a new column (called which_part for example) saying if the date (in this case date is in "sil.sales_invoice_date") is between 1st of january to 30th of june - which should say H1 (half 1) and else is H2 (between 1st of july to end of the year).
I've tried doing something like that with convert
SELECT
sil.sales_invoice_date AS "Distributor Invoice Date",
CONVERT(sil.sales_invoice_date, #year + '-01-01') AS [start year],
CONVERT(sil.sales_invoice_date, #year + '-06-30') AS [end year],
It doesn't work at all and I can't write [half year] in there.
I've also tried to do it by using
case sil.sales_invoice_date between
But I don't really know how to format it to work with variable year.

if you have date in format dd.mm.yyyy
Try this
Case when substr(sil.sales_invoice_date,1,5) between '01.01' and '30.06' then 'H1'
else 'H2'
end as which_part;

Related

Combine and convert nvarchar month field + float year field to a single date field

I have a table in SQL Server 2012 with a month column stored as nvarchar(255):
"January", "February", "March"
And another column in this table with year stored separately as float
"2012","2013,"2014".
I do not have a day column so I want to create a combined month date column with the day starting as 1.
So for month and year fields January 2012. I want to show '2012-01-01'
How can I do such and add that into my current table?
I want to find the maximum row for a record in my table for each employee.
so for an [employee #], [month],[year]. what is latest record so for example below:
1. 102, Jan, 2019
2. 102, feb, 2019
I want to only see the second record which is the latest.
SQL Server has pretty flexible conversion to date. So, just convert the columns to a date:
select convert(date, month + ' ' + year)
You can get the maximum as:
select empid, max(convert(date, month + ' ' + year))
from t
group by empid;
If you really like, you can change the format for output purposes. I would advise you to stick with a date, though.
Note: This assumes that your internationalization settings are set to English -- which seems reasonable if you are storing month names in English.
Fix your design! The way you store data makes it really inefficient to interpret it. Here, I think the simplest option is datefromparts() and a 12-branches case expression.
Assuming that the (float) year is stored in column col_year and the (string) month is in col_month:
select t.*,
datefromparts(
cast(col_year as int),
case col_month
when 'January' then 1
when 'February' then 2
...
when 'December' then 12
end,
1
) as date_col
from mytable t

Last Month to Date

I am trying to calculate the sales for last month to date.
I have created the month to date as the following:
sum(case when year(s.bus_dat) = year(getdate()) and month(s.bus_dat) = month(getdate())
then qty_sold end) as MTD_SAL,
I need to create the last month to date in a similar way (I want the code represent the date from the beginning of last month til today so if today is 10/28/2018 I need to show all the sales from 09/01/2018 to 10/28/2018
Any advice please?
Calculate the first day of the month, then go back a month using this:
dateadd(m,-1,dateadd(d,-day(getdate())+1,getdate()))
Need to make sure its the start of the day, so convert to date:
convert(date,dateadd(m,-1,dateadd(d,-day(getdate())+1,getdate())))
So your complete columns becomes:
sum(case when s.bus_dat>=
convert(date,dateadd(m,-1,dateadd(d,-day(getdate())+1,getdate()))))
then qty_sold else 0 end) as LM
To get something between last month and today you can use :
BETWEEN DATE(CONCAT(YEAR(NOW()),'-',MONTH(NOW()),'-01')) - INTERVAL 1 MONTH AND DATE()

Create a sql query based on selected month from dropdown combobox in excel userform

I have a userform in excel for attendance reporting. On the form the user chooses the employee they want to review, and then they can check a box that says year to date, or select individual months from a combobox drop down. This is all to query our sql server that has the data on it. Year to date is easy, because I know how to use the variables for current date and first day of the year. What I'm having trouble with is how to convert the user's month selection into a usable query. For example: If the user selects January for the drop down, the query would be
select * from [dbo.mytablename]
where [agent name] = '<value from a textbox that I know how to pass in>'
and [cal date] > '1/1/2018' and [cal date] < '1/31/2018'
Right now my only idea is to have cells on a holding spreadsheet in the workbook that have the first and last day of each month and then use the cell values. But I'd like to avoid that if possible. If you have any ideas that would be great!
First of all
and [cal date] > '1/1/2018' and [cal date] < '1/31/2018'
will select all data from Jan 1 to Jan 30 and not include any data from Jan 31.
Keeping this in mind, the check should be
and [cal date] > '1/1/2018' and [cal date] < '2/1/2018'
So if you do get a month from drop down you can do something like below
select * from [dbo.mytablename] t
join
(values
('Jan', 1),('Feb',2),('Mar', 3),
('Apr', 4),('May',5),('Jun', 6),
('Jul', 7),('Aug',8),('Sep', 9),
('Oct', 10),('Nov',11),('Dec', 12)
)v(mon,num)
on v.mon='<month name received from a text box>'
t.[agent name] = '<value from a textbox that I know how to pass in>'
and t.[cal date] > cast(cast(v.num as varchar)+'/1/2018' as date)
and t.[cal date] < cast(cast((v.num+1)%12 as varchar)+'/1/'+ cast(2018+ (v.num/12) as varchar) as date)
In SQL Server there are numerous techniques for date calculation/converions. If 2012+ you can use EOMonth() or DateFromParts().
I should also add [cal date] < '1/31/2018' should be [cal date] <= '1/31/2018'
Example
Select StrCast1 = try_convert(date,concat('January',' 1, ',2018))
,StrCast2 = EOMonth(try_convert(date,concat('January',' 1, ',2018)))
,FromParts1 = DateFromParts(2018,1,1)
,FromParts2 = EOMonth(DateFromParts(2018,1,1))
Returns
StrCast1 StrCast2 FromParts1 FromParts2
2018-01-01 2018-01-31 2018-01-01 2018-01-31
Assuming your month is a numeric value between 1 and 12, you can use something like
Dim fromDate As Date, toDate As Date
fromDate = DateSerial(2018, month, 1)
toDate = DateSerial(2018, month + 1, 1)
Debug.Print fromDate, toDate
This will work even with December, DateSerial accepts a 13 as month.
Note that you have to ask for < first day of next month to catch data from the last day of the month.
Side note: I assume you use a ADODB.Command to query the database. I would strongly suggest that you use ADODB.parameter to pass the dates (and the agent name) to the database - you don't have to deal with formatting or converting the dates so that the database understand them correctly. See for example https://stackoverflow.com/posts/10353908/edit to get an idea how this works.
Update
I assume you fill your combo box with values from a range and the value is linked to a cell. Use for example the match function to get the month as number (I would never trust that the name of a month is translated correctly by Excel or the database, there are too many things like regional settings that could cause that it breaks).
Assuming:
Range with month names: A1..A12
Linked cell: B1
Put the formula =MATCH(B1,A1:A12) in cell B2. VoilĂ , you have the number of the month.

Get Year of Previous Month (For Jan 1st)

I'm currently building a YTD report in SSRS. I'm looking to edit the default "FROM" date in a calendar selection.
I'm looking to retrieve January 1st of the previous months year. For example:
(If it's Feb 16th, 2016 .. the result should be 1/1/2016
If it's Jan 10th, 2016 .. the result should be 1/1/2015)
I built this to retrieve the current year for jan 1st, but it causes issues if we're in January because I need it to retrieve the year of the previous month (in that case it would be 2015, not 2016).
Thanks!
Try this, it should work
=DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1))
UPDATE:
Based on your comment I've created this expression. It is not tested but should work.
=IIF(Today.Month>1,
DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1)),
DateAdd(DateInterval.Year,-1,DateSerial(Year(Today), Month(Today), 1))
)
Let me know if this helps.
select cast(cast(year(dateadd(mm, -1,getdate())) as varchar)+'-01-01' as date)
replace getdate() with which ever field you're basing this calculation on.
for testing:
select cast(cast(year(dateadd(mm, -1,'2015-01-22')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2016-02-01')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2015-12-12')) as varchar)+'-01-01' as date)
We want to use Date Serial which has the forma
=DateSerial(YYYY,MM,DD)
The Month is always January
The day is always the first
If the month is January, it's last year. Otherwise, it's this year.
So, assuming we have an SSRS report with a parameter called Date , we can create a new field for your January date as follows:
=iif(Month(Parameters!Date.Value)=1,
dateserial(Year(Parameters!Date.Value)-1,1,1),
dateserial(Year(Parameters!Date.Value),1,1))
if you want to do this in the query with T-SQL (version 2012) or later:
case when month(#DATE) = 1
then DATEFROMPARTS(YEAR(#DATE)-1,1,1)
else DATEFROMPARTS(YEAR(#DATE),1,1)
end
OR, in earlier versions
CASE WHEN MONTH(#DATE) = 1
THEN CAST(CAST((YEAR(#DATE)-1)*10000 + 101 AS CHAR(8)) AS DATE)
ELSE CAST(CAST((YEAR(#DATE)*10000+ 101) AS CHAR(8)) AS DATE)
END

Finding the last day of the week

I have a table with a bunch of dates (option maturity dates to be precise). I need to query this database to find the last day of a specific week that is stored in the table.
All I will be given to query this table is the year, the month and the specific week. And based on this I need to find the date that is stored in the table that matches this.
I've created the following query to find this specific date March 28 2013
SELECT M_SETNAME, M_LABEL, M_MAT FROM OM_MAT_DBF
WHERE M_SETNAME = 'IMM_OSET '
AND MONTH(M_MAT) = 3
AND YEAR(M_MAT) = 2013
AND ((DATEPART(day,M_MAT)-1)/7 + 1) = 5
Do you guys have any idea of how I can change the last condition so that March 28th will be considered the 5th week of the month and not the 4th week as it is currently doing.
You can also use DATEPART to get the number of the week (in the year), but then, you could also get the 1st of each month, and take the week too so you can have: WEEK OF MY DATE - WEEK OF FIRST DAY FOR THIS MONTH + 1.
Here you have an example...
DECLARE #Dt datetime
SELECT #Dt='03-28-2013'
SELECT DATEPART( wk, #Dt) - DATEPART( wk, Convert(Date,Convert(varchar(4),YEAR(#Dt))
+ '-' + Convert(varchar(2), MONTH(#Dt))
+ '-' + Convert(varchar(2), 1))) + 1
EDIT: Also, looking at your code, you could add the CEILING. If the result == 2.7, it means it passed the 2nd week, however, it gets rounded to 2 when it should actually be 3.
If you add the CEILING and the CONVERT to decimal should work..
SELECT MONTH(#Dt),
YEAR(#Dt),
((CEILING(Convert(decimal,DATEPART(day,#Dt)-1)/7)) + 1)