Fetch month name based on various dates in table - sql

I have one table that contains BillDate column i.e. Bill Dates for various customers. The bill date range from September 1 to September 30. Based on the billdate, I want to fetch Month name in format "Sep-19" (19 being year 2019)
The issue is that from next month, the BillDate will have records for both September and October 2019.
For Oct 2019, the bill month that I want to fetch is "Oct-19" as I will create a report based on data present for bills in October month.
How to fetch bill month based on data that changes every month?

One method uses format():
select format(BillDate, 'MMM-yy')
A more old-fashioned method constructs the string:
select left(datename(month, BillDate), 3) + '-' + right(datename(year), BillDate), 2)

FORMAT is an awful function for this, it's horrifically slow. I highly recommend CONVERT and a style code, along with some string manipulation.
REPLACE(STUFF(CONVERT(varchar(11),BillDate,106),1,3,''),' ','-')

You can try this:
SELECT REPLACE(RIGHT(CONVERT(VARCHAR(20), BillDate, 106), 8), ' ', '-')
For Getting Most Recent Data you can try this
SELECT REPLACE(RIGHT(CONVERT(VARCHAR(20), BillDate, 106), 8), ' ', '-') AS 'YourColumnName' FROM TableName
ORDER BY BillDate DESC
For Testing Purpose:-
SELECT REPLACE(RIGHT(CONVERT(VARCHAR(20), GETDATE(), 106), 8), ' ', '-') AS 'CurrentDate'
Output:-
CurrentDate
-----------
Oct-2019

Use the format function to convert the date in your format. And then you can use the where function to get the results for current month (oct 2019).
Note: Format is small and nice function if you're using to build this report query for small data. But if you're working with relatively large datasets I would recommend convert as format would have affect on performance.
Select *
From
(select your_field1, your_field2, format(BillDate, 'MMM-yy') as Current_Date from your_table) as alias_table
Where [Current_Date] = format(GETDATE(), 'MMM-yy');
In SQL you cannot use alias columns names within the same query that is why I have used a subquery in paranthesis to force SQL to handle where before select.

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

Presto how to find start date given week

I want to find start date from given ISO week (which can range from 1-53, Monday as starting day) and year using Presto SQL query.
i.e. year - 2020 and week - 2 should return 06/01/2020
Is there any inbuilt function for this ?
Table structure:
select year, week from table1; // returns year and week from table table 1
There's no direct way for constructing a date from a year + week (there is an issue for this: https://github.com/trinodb/trino/issues/2287), but you can achieve what you want with the date_parse function.
For example:
WITH data (year, week) AS (VALUES (2020, 2))
SELECT CAST(date_parse(CAST(year AS varchar) || ':' || CAST(week AS varchar), '%x:%v') AS date)
FROM data
produces:
_col0
------------
2020-01-06
(1 row)
Using DATE_ADD and MAKEDATE you can achieve the result...
select DATE_ADD(MAKEDATE(year, 1), INTERVAL (week-1) WEEK) as start_date from <table_name>;
Martin's answer is almost there. Instead of using year, you should use year_of_week. Though with this change you'll have to make sure to not have a bug with weeks that bleed into the following or previous year i.e. last days of the previous year or first days of the next year.
year_of_week returns the year of the ISO week.
Here's an example:
WITH data (year, week) AS (VALUES (2020, 2))
SELECT CAST(date_parse(CAST(year_of_week AS varchar) || ':' || CAST(week AS varchar), '%x:%v') AS date)
FROM data
References:
https://prestodb.io/docs/current/functions/datetime.html#year_of_week
https://en.wikipedia.org/wiki/ISO_week_date
I think for partial weeks (when first days in a new year is still counted as week 53) this does not work:
Query failed (#20210624_142222_02859_zf75v): Cannot parse "2021:53": Value 53 for weekOfWeekyear must be in the range [1,52]
tested by this formula:
The date was on Jan 2,2021 which is still treated as week53 but in 2021...
CAST(date_parse(CAST(year(date(service_order_creation_date)) AS varchar) || ':' || CAST(week(date(service_order_creation_date)) AS varchar), '%x:%v') AS date)

Create date column using year and month columns to yyyymmdd

I have a year column that contains things like 2013, 2012, etc and a month column that displays 1-12. I need to use these columns to create a date that always pulls the last day of the month that the year and month represents as yyyymmdd. For example, if year = 2018 and Month = 3, I need the date to display as 20180331. The year and month fields are numeric. I am using SQL Server 2014 Management Studio Any ideas on how to do this?
You could shoe horn it this way:
select REPLACE(CAST(EOMONTH(DATEFROMPARTS(2018,2,1)) as varchar(20)), '-','')
I was able to find a formula that works, although the answer above is smaller in code and may be a more efficient way to accomplish the same thing, which I can test out. Here is the code that I was able to get to work for those interested.
CONVERT(VARCHAR(10),eomonth(CAST(CAST(FV_RPT_EMPLOYEECENSUS_ASOF.HRYEAR AS VARCHAR(4)) + RIGHT('0' + CAST(FV_RPT_EMPLOYEECENSUS_ASOF.HRPERIOD AS VARCHAR(2)), 2) + RIGHT('0' + CAST(01 AS VARCHAR(2)), 2) AS DATE)),112)

Convert date into individual numerical columns for year month and day SQL

I have a date column in the format YY-MON-DD, e.g. 25-JUN-05. Is it possible to isolate this into 3 separate columns for year, month and day? Where month is converted from text to numerical, e.g. Year: 25, Month: 06, Day: 05?
MS SQL SERVER
As Nebi suggested, you can use DATEPART and extract each part and store it into different columns.
SELECT DATEPART(DAY,'2008-10-22'); -- Returns DAY part i.e 22
SELECT DATEPART(MONTH,'2008-10-22'); -- Returns MONTH part i.e 10
SELECT DATEPART(YEAR,'2008-10-22'); -- Returns YEAR part i.e 2008
Try with the below script,if you are using SQL Server.
SELECT 'Year: '+CAST(LEFT(YourdateColumn,2) as VARCHAR(2))+', Month: ' +CAST(MONTH('01-'+SUBSTRING(YourdateColumn,4,3)+'-15')as VARCHAR(2))+', Day:'+CAST(RIGHT(YourdateColumn,2)as VARCHAR(2))
FROM Yourtable
sample output :
You didn't specify your DBMS.
The following is standard SQL assuming that column really is a DATE column
select extract(year from the_column) as the_year,
extract(month from the_column) as the_month,
extract(day from the_column) as the_day
from the_table;

How do I do a comparison with just a month and year, not a complete date?

I need to write a stored procedure to allow someone to search a db. However, all I get are ints for month and year. And the db has month and year fields. But I can't figure out how to set up the comparison.
Ex: I get March 2008 and June 2010.
I need to searhc the database for records where the date, as specified by the month and year fields, are between thoese two dates.
Edit
Given two Date inputs, how do I find all records that fall between those dates? Each record only has integers representing year and month.
Previous solutions should work, but unfortunately they prevent using index on year and month columns.
You will probaly have to wirte it the hard way:
SELECT *
FROM records
WHERE Year > #StartYear
OR ( Year = #StartYear
AND Month >= #StartMonth)
/*(ommited end date check, it is same)*/
Another possibility is to add computed date column to source table
Storing date this way is suspicios and probably incorrect from DB design point of view. Consider storing date in date column and (if you really need it) adding computed columns for year and month.
Assuming you are provided Date variables called #StartDate and #EndDate in SQL Server:
SELECT
*
FROM
MyTable
WHERE
-- yields "200901 between 200801 and 201104" on inputs 01-01-2008, 04-01-2011
Convert(VarChar(10), MyTable.Year) + Replace(Str(MyTable.Month, 2), ' ', '0')
BETWEEN
Convert(VarChar(10), YEAR(#StartDate)) + Replace(Str(MONTH(#StartDate), 2), ' ', '0')
AND
Convert(VarChar(10), YEAR(#EndDate)) + Replace(Str(MONTH(#EndDate), 2), ' ', '0')
References
Simple Left-Padding for Int to String Conversion - Inspired Replace(Str(MyTable.Month, 2), ' ' , '0')
TSQL Between
An unconventional approach:
select * from sometable
where YourYear * 100 + YourMonth
between #SomeStartYear * 100 + #SomeStartMonth and #SomeendYear * 100 + #SomeEndMonth