CONCAT columns without sub-query SQL Server - sql

I was looking to see if there was a better approach to this query
The date field is formatted - 06-03-2018
I need a column that looks like e.g. Mar-18
e.g
SELECT
CONCAT(P.[Month] + '-', p.[Year]) AS [Month-Year]
FROM
(
SELECT
left(datename(MONTH,[Date]),3) AS [Month]
,right(YEAR([Date]),2) AS [Year]
FROM
Table1
)P
This gives me the result i want but i was wondering if there was anyway to get the same result without a sub-query. Thanks

Why not just format the date as
select format(convert(date, '06-03-2018', 103), 'MMM-yy')

The query you've provided isn't valid, you need a comma (,) between column declarations (which you're missing.
Anyway, the query can be simplified to:
SELECT LEFT(DATENAME(MONTH,[Date]),3) + '-' + RIGHT(YEAR([Date]),2) AS [Month-Year]
FROM Table1;
I haven't used CONCAT here, as there is no need (as either both values will be NULL or have a value).

You Can Do the concatenation directly
SELECT
CAST(LEFT(datename(MONTH, [Date]), 3) AS VARCHAR(20))
+'-'+
CAST(RIGHT(YEAR([Date]), 2) AS VARCHAR(20))
FROM Table1;

Related

Change the format of joining date to month-day,year sql

Change the format of joining date to month-day,year for e.g. January 31,1992.
Query
select ename, to_char(joining_date,'Month DD,YYYY.') from emp_demo ;
Error
'to_char' is not a recognized built-in function name.
Table emp_demo format
joining_date
1992-01-31
You seem to be looking to display your date in a given format (which is what to_char() does in Oracle).
In SQL Server, you can use format():
select ename, format(joining_date, 'MMMM dd,yyyy.')
Demo on DB Fiddle:
select format(getdate(),'MMMM dd,yyyy.')
Yields:
May 04,2020.
SQL Server is pretty good about converting dates without a format. Try:
select cast(joining_date as date)
from emp_demo;
Here is a db<>fiddle.
For the inverse transformation, you want to use format() with the format 'MMMM dd,yyyy'.
You can try this query.
Select Convert(Varchar(7), CONVERT(Varchar(20), getdate(), 100))
+ ', ' + Cast(year(getdate()) as varchar(4)) as StatusOn
Select CAST(GETDATE() AS CHAR(3)) + ' ' + CONVERT(char(2), getdate(), 103) + ', '+
CONVERT(char(4), year(getdate())) as StatusOn
Output

How can I convert an integer like 3212007 to date 3-21-2007 uisng IBM DB2 SQL?

The dataset I inherited has a DATE column but the values in this column are integers of the form 3212007 which should be 03-21-2007. I can't get it back into date format.
I can convert the integer to a string using CAST(myinteger as varchar(8)) without difficulty. Then I can CAST that as date by CAST(CAST(myinteger as varchar(8)) as date) which gets me a date. The problem is that my integer is formatted as 'mmddyyyy' so for 3212007, I get 3212-01-07.
select TRANSACTION_DATE from MA_NORFOLK fetch first row only;
[returns: 3212007]
select CAST(TRANSACTION_DATE as VARCHAR) from MA_NORFOLK fetch first row only;
[returns: 3212007]
select CAST(CAST(TRANSACTION_DATE as varchar(8)) as date) from MA_NORFOLK fetch first row only;
[returns: 3212-01-07]
Other posts suggest using CONVERT command, but all I get are errors
"DATE" is not valid in the context where it is used..."
Could you please advise me?
Try this:
date(to_date(digits(dec(3212007, 8)), 'MMDDYYYY'))
If you may have one digit for month, there is an alternative:
select
date
(
case when substr(char_dt, 1, 2)='00'
then translate('EFGH-0D-0C', char_dt, 'ABCDEFGH')
else translate('EFGH-AB-CD', char_dt, 'ABCDEFGH')
end
) dt, char_dt
from
(
select digits(dec(i, 8)) char_dt
from table(values 3212007, 312007) t(i)
) t;
DT CHAR_DT
---------- --------
2007-03-21 03212007
2007-01-03 00312007
This works (at least in MS SQL Server):
SELECT CAST(CONCAT( RIGHT(3212007,4),'-',
(3212007 / 1000000), '-', ((3212007 % 1000000) / 10000)) AS date)
The trick is that you don't know if you will have a single digit, or two-digit month, so you have to start with getting just the right 4 characters as the year. Then by using combinations of modulo and integer divide, you can parse out the month and day.
Of course, you will want to substitute your actual date column for the sample data that I used above.
I think this may works well:
create table #temp(
date int
)
insert into #temp (date)
values(3212007),
(12032019)
select
case when len(cast(date as varchar)) = 7
then
'0' + left(cast(date as varchar), 1) + '-' + substring(cast(date as varchar), 2,2) + '-' + right(cast(date as varchar), 4)
else left(cast(date as varchar), 2) + '-' + substring(cast(date as varchar), 3,2) + '-' + right(cast(date as varchar), 4) end
from #temp

Combining date and time fields in ETL SQL Query

I have multiple date and time fields that I need to combine into a datetime in a SQL Query. I unfortunately cannot change the initial database structure to combine them in the original server.
I can combine the SQL Query data after export, but because of the problem of flat files conversion, and the possibility of data corruption/loss, I am hesitant as I would need to convert the flat file twice.
These are the things I've tried:
SELECT Combine = cast([DateValue] as datetime) + Cast([TimeValue] as datetime)
Unfortunately, this leads to errors where I have fewer columns than original fields....
The original Query looks like this:
SELECT
Ordered_Date.DateValue,
Ordered_TOD.TimeValue,
Start_Date.DateValue,
Start_TOD.TimeValue,
End_Date.DateValue,
End_TOD.TimeValue,
Discontinued_Date.DateValue,
Discontinued_TOD.TimeValue
FROM
warehouse_report...........
WHERE
( ..... )
If I add The Combine command into the SQL query, it seems to working in that it is combining the date/time. The issue is that when I implement this in the SELECT section of the SQL Query, I have 1 less column and it won't let me execute the script...
SELECT
Ordered_Date.DateValue,
Ordered_TOD.TimeValue,
Start_Date.DateValue,
Start_TOD.TimeValue,
COMBINE = CAST(End_Date.DateValue as datetime) + CAST(End_TOD.TimeValue as datetime),
Discontinued_Date.DateValue,
Discontinued_TOD.TimeValue
FROM
warehouse_report...........
WHERE
( ..... )
This gives me one less column on the output of the SQL Query...
How about concatenate the values and parse:
SELECT cast([DateValue]||' '||[TimeValue] as datetime)
Please, provide the information about which SGBD you are using to get a better answer.
Edit1:
To SQL Server:
Select
x.d1
From (
Select
convert(datetime, '2018-01-01 00:00:00.0', 121) d1
) x
Union All
Select
convert(datetime,
substring(convert(varchar, x.d1, 121), 1, 11)
+ substring(convert(varchar, x.t1, 121), 11, 13)
, 121)
From (
Select
convert(datetime, '2018-01-01 00:00:00.0', 121) d1,
convert(datetime, '10:00:22') t1
) x

SQL Server ORDER BY when using DATENAME function

SELECT CAST(DATEPART(yyyy,DATE1)
AS varchar (5)) + '-' + CAST(DATENAME(m,ec2.DATE2)
AS varchar(3)) AS [Month],
CAST(AVG(CAST(DATEDIFF(day,DATE1, DATE2)
AS DECIMAL(10,2))) AS DECIMAL(10,2)) AS tt
FROM tbl3
GROUP BY CAST(DATEPART(yyyy,DATE1) AS
varchar (5)) + '-' + CAST(DATENAME(m,ec2.DATE2)
AS varchar(3))
ORDER BY [Month]
So in the above query I have results for 2 different years so its sorting year in integer wise but Month according to alphabets(as its DATENAME)
Examples:
2013-Dec 4.45
2013-Nov 5.55
2014-Jan 2.35
2014-Jan 2-85
The problem is I am using DATE2 in my aggregate function(Avg) and hence can't use it in ORDER BY clause.
Anyone has a solution for this problem. I will be really thankful if you can help me. I read other questions regarding this problem but didn't find the solution.
Thanks in advance.
A convoluted way, but works in any situation. Use CTE to solve your issue as below:
With CTE as (
SELECT CAST(DATEPART(yyyy,DATE1)
AS varchar (5)) + '-' + CAST(DATENAME(m,ec2.DATE2)
AS varchar(3)) AS [Month],
CAST(AVG(CAST(DATEDIFF(day,DATE1, DATE2)
AS DECIMAL(10,2))) AS DECIMAL(10,2)) AS tt
FROM tbl3
GROUP BY CAST(DATEPART(yyyy,DATE1) AS
varchar (5)) + '-' + CAST(DATENAME(m,ec2.DATE2)
AS varchar(3))
Select * from CTE
ORDER BY
DATEPART(yyyy, cast([Month] as datetime)),
DATEPART(mm, cast([Month] as datetime));
I agree you can order by Year/Month as Darius X suggested. You can also use a cross apply to "wrap" your calculation. Not sure it would solve your specfic problem, but for additional information. I figure out the MatchStatus in the CROSS APPLY then use MatchStatus in the SELECT & GROUP BY clauses.
SELECT
MatchStatus,
COUNT(*)
FROM MPI.ACTData.Matches
CROSS APPLY (SELECT CASE WHEN MatchScore >= 69 THEN 'Match'
ELSE 'Review' END MatchStatus) ms
GROUP BY MatchStatus

Get 2 Digit Number For The Month

I have an integer column "Month"
I would like to get 2 digit number for month.
This is what I have tried: DATEPART(mm, #Date)
It returns one digit for months January to September
I am using SQL Server 2008
Anyone has suggestion?
Function
FORMAT(date,'MM')
will do the job with two digit.
there are different ways of doing it
Using RTRIM and specifing the range:
like
SELECT RIGHT('0' + RTRIM(MONTH('12-31-2012')), 2);
Using Substring to just extract the month part after converting the date into text
like
SELECT SUBSTRING(CONVERT(nvarchar(6),getdate(), 112),5,2)
see Fiddle
There may be other ways to get this.
Pinal Dave has a nice article with some examples on how to add trailing 0s to SQL numbers.
One way is using the RIGHT function, which would make the statement something like the following:
SELECT RIGHT('00' + CAST(DATEPART(mm, #date) AS varchar(2)), 2)
Another simple trick:
SELECT CONVERT(char(2), cast('2015-01-01' as datetime), 101) -- month with 2 digits
SELECT CONVERT(char(6), cast('2015-01-01' as datetime), 112) -- year (yyyy) and month (mm)
Outputs:
01
201501
CONVERT(char(2), getdate(), 101)
Alternative to DATEPART
SELECT LEFT(CONVERT(CHAR(20), GETDATE(), 101), 2)
SQLFiddle Demo
append 0 before it by checking if the value falls between 1 and 9 by first casting it to varchar
select case when DATEPART(month, getdate()) between 1 and 9
then '0' else '' end + cast(DATEPART(month, getdate()) as varchar(2))
For me the quickest solution was
DATE_FORMAT(CURDATE(),'%m')
Simply can be used:
SELECT RIGHT('0' + CAST(MONTH(#Date) AS NVARCHAR(2)), 2)
Try:
select right ('0'+convert(nvarchar(2), DATEPART(mm, getdate())),2 )
My way of doing it is:
right('0'+right(datepart(month,[StartDate]),2),2)
The reason for the internal 'right' function is to prevent SQL from doing it as math add - which will leave us with one digit again.
SELECT REPLACE(CONVERT(varchar, MONTH(GetDate()) * 0.01), '0.', '')