Extract values from dates and concat them - sql

I have a table that contains date in format YYYYMMDD like 20230120. I need to build string that contains: current date + year from block_date + month from block_date with - delimeter :
SELECT
CONCAT(TO_CHAR(CURRENT_DATE, 'DD.MM.YY'), '_', EXTRACT (year from to_date(block_date::text, 'yyyymmdd')), '_', EXTRACT (month from to_date(block_date::text, 'yyyymmdd')))
from test
It returns:
20.01.23_2023_1 but I expect 20.01.23_2023_01
I have 2 questions:
For month from block_date i expect 2 digits, like 01, 02, 11...
Can I simpify my select?

Use to_char() on the converted date as well:
CONCAT(TO_CHAR(CURRENT_DATE, 'DD.MM.YY'), '_', to_char(to_date(block_date::text, 'yyyymmdd'), 'yyyy_mm'))

Related

How do I get yyyy-mm format from 2 different columns in SQL?

I have 1 column that displays year number in the format 1999 and I have another column that displays month number as 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.
How do I get the single months to display with a 0 in front? I need to combine these 2 columns to display in the form of yyyy/mm so it will be 1999/01 for January 1999.
I tried:
SELECT
YearNumber + '/' + FORMAT(MonthNumber, 'mm') AS PaymentMonth
But I get this error:
Conversion failed when converting the varchar value '/' to data type smallint
Please try:
SELECT
CAST(YearNumber AS varchar(4)) + '/' +
LEFT('0' + CAST(MonthNumber AS varchar(2)), 2) AS PaymentMonth;
Another option, using case when:
The table:
select * from mytable
# YearNumber MonthNumber
# 1999 2
# 2000 11
select YearNumber || '/' ||
(case when MonthNumber < 10 then '0' else '' end) ||
MonthNumber as YearMonth
from mytable
# YearMonth
# 1999/02
# 2000/11
Note: the above works in sqlite, which tends to be more permissive with column types. In SQL Server, if the columns are not strings already then you may need to cast(YearNumber as char(4)) or perhaps use the concat function:
select
concat(YearNumber, '/',
(case when MonthNumber < 10 then '0' else '' end),
MonthNumber) as YearMonth
from mytable
Other DBMSes have different dialects, they may differ slightly.
SQL Date Format with the FORMAT function
Use the FORMAT function to format the date and time data types from a date column (date, datetime, datetime2, smalldatetime, datetimeoffset, etc. data type) in a table or a variable such as GETDATE()
To get DD/MM/YYYY use SELECT FORMAT (getdate(), 'dd/MM/yyyy ') as date
To get MM-DD-YY use SELECT FORMAT (getdate(), 'MM-dd-yy') as date.
You can use the concat() function to join them. Depending on the database you can use || instead.
select concat(col1, '/', col2) from tbl;
This is also standard, but not enabled by default on MySQL, and possibly other databases.
select col1 || '/' || col2 from tbl;

SQL Query to Combine Dates

I have a data set that has dates like this:
MM DD YY
2 8 10
3 9 11
4 10 12
I'm trying to write a query that displays the dates in one single column as MM/DD/YY
Any help would be greatly appreciated thanks
If you dont mind the data format, you can concatenate them.
select MM || '/' || 'DD' || '/' || YY DATE_COL from T
you can also convert it to date
select to_Date(MM || '/' || 'DD' || '/' || YY, 'MM/DD/YY') DATE_COL from T
Teradata actually stores dates as integers, as explained in the documentation:
Teradata Database stores each DATE value as a four-byte integer using the following formula: (year - 1900) * 10000 + (month * 100) + day.
If you want to generate a result of date datatype from your numbers, you can just do:
cast((yy + 100) * 10000 + mm * 100 + dd as date)
On the other hand, if you just want a string in format mm/dd/yy, it is probably simpler to use string functions; we just need to pad the 1-digit values with 0:
lpad(mm, 2, '0') || '/' || lpad(dd, 2, '0') || '/' || lpad(yy, 2, '0')
You can do below, assuming your year is in the 21st century.
select to_Date(lpad(MM,2,'0')|| '/' ||lpad(DD,2,'0')|| '/20' ||lpad(YY,2,'0'),'MM/DD/YYYY') as Date_field
from my_Table;
Here is a demo in Oracle - https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=1ba6814d793f2b8b269611e348540f6c. This would work in Teradata as well.

How to do this Query (String combination)

i have the data which look like this
Day Month Time
11 02 12:11:11
12 02 10:10:20
13 02 9:12:6
14 02 6:7:2
as you can see the data in Time Column is not Timestamp but String, therefore some of The Data has the wrong Format like this: 9:12:6 not 09:12:06.
what i want to do now is a new Colum which combine String of Day, Month, and correct Time Format, the ":" need to be removed.
The Result should looks like this:
new Colum
1102121111
1202101020
1302091206
1402060702
Can you please help me?
Thanks
CREATE TABLE Saletime (
day VARCHAR(02) NOT NULL,
month VARCHAR(02) NOT NULL,
time VARCHAR(10) NOT NULL);
INSERT INTO saletime(day, month, time) VALUES ('11','02','12:11:11');
INSERT INTO saletime(day, month, time) VALUES ('12','02','10:10:20');
INSERT INTO saletime(day, month, time) VALUES ('13','02','9:12:6');
INSERT INTO saletime(day, month, time) VALUES ('14','02','6:7:2');
Concatenate the values then parse them
select to_char(
to_timestamp(
day||'-'||month||' '||time,
'DD-MM HH24:MI:SS'),
'DDMMHHMISS')
from Saletime;
SQL Fiddle example
Since the inputs and the output are all strings, perhaps direct string manipulation makes sense. (It would be much better if the output were date data type, but that is in your hands, not in mine.)
I follow your lead in using day and month as column names. That is a very poor practice; I hope your actual column names are different.
It's not clear if you may need the same left-padding with 0 for the day and month; just in case, I handled it too (it's done the same way).
select day, month, time,
lpad(day, 2, '0') || lpad(month, 2, '0')
|| lpad(regexp_substr(time, '\d+', 1, 1), 2, '0')
|| lpad(regexp_substr(time, '\d+', 1, 2), 2, '0')
|| lpad(regexp_substr(time, '\d+', 1, 3), 2, '0') as new_string
from saletime;
DATE MONTH TIME NEW_STRING
---- ----- --------- ----------
11 02 12:11:11 1102121111
12 02 10:10:20 1202101020
13 02 9:12:6 1302091206
14 02 6:7:2 1402060702
You can do this as a numeric calculation:
select (day * 100000000 +
month * 1000000 +
cast(regexp_substr(time, '[0-9]+', 1, 1) as number) * 10000 +
cast(regexp_substr(time, '[0-9]+', 1, 2) as number) * 100 +
cast(regexp_substr(time, '[0-9]+', 1, 3) as number) * 1
)
from saletime;
Here is a SQL Fiddle.
If you want this as a string, just convert it to a string.

Combining date , month , year columns in SQL Server

DD(10)-MM(05)-YYYY(2013)
I have a table with DATE, MONTH, YEAR in separate columns. How I can combine them into a single column Created date?
Output must be: 10-05-2013 (DD-MM-YYYY format)
SELECT RIGHT('00' + DAY, 2) + '-' + RIGHT('00' + MONTH, 2) + '-' + YEAR AS Date
FROM YourTable
I guess you want have a date field instead of a string. So use TO_DATE() function. You can format date anyway you want later.
TO_DATE(YEAR + '/' + MONTH + '/' + DATE, 'yyyy/mm/dd')
You can do it easily:
SELECT to_char(TO_DATE('10 01 2014', 'DD MM YYYY'),'dd-mm-yyyy') AS MYDATE FROM DUAL
To concatenate columns you just need to use "+" in your select statement
SELECT DATE + '-'+ MONTH + '-'+ YEAR FROM table

Varchar m/d/yyyy to yyyy/mm/dd sql

I have a file that inputs data in the format m/d/yyyy or m/dd/yyyy depending on whether or not the date value is 2 digits (example 4/1/2015 or 4/14/2015). I need to convert this to a date with the format yyyy/mm/dd (example 2015/04/01 or 2015/04/14). I have tried multiple way but I get the error "Invalid date" every time. Please help.
Things I have tried:
cast((CASE WHEN CHAR_LENGTH(RSA_dt) <10 THEN 0 || TRIM(RSA_dt) end) AS DATE)
CAST( CAST( RSA_dt AS DATE FORMAT 'DD-MMM-YY') AS DATE FORMAT 'YYYY-MM-DD')
cast(RSA_dt as date format 'YYYY-MM-DD')
Which tool do you use for loading?
The easiest way to load this data is to define that column as a VARDATE in a TPT job:
VARDATE(10) FORMATIN 'MM/DD/YY' FORMATOUT 'YYYY-MM-DD'
Otherwise you got a problem as Teradata's CAST doesn't like single digit day/month. Starting with TD14 there's Oracle's TO_DATE, which still doesn't like a single digit month, but at least tolerates single digit day:
TO_DATE(CASE
WHEN RSA_dt LIKE '_/%'
THEN '0' || RSA_dt
ELSE RSA_dt
END
,'mm/dd/yyyy')
This will work for TPT.
Select '1/1/2014' as date1,
TO_DATE (
case
when strtok(date1, '/', 1) between 1 and 9 and strtok(date1, '/', 2) between 1 and 9 then strtok(date1,'/', 3)||'/0'||strtok(date1, '/', 1)||'/0'||strtok(date1,'/', 2)
when strtok(date1, '/', 1) between 1 and 9 and strtok(date1, '/', 2) > 9 then strtok(date1,'/', 3)||'/0'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
when strtok(date1, '/', 1) > 9 and strtok(date1, '/', 2) between 1 and 9 then strtok(date1,'/', 3)||'/'||strtok(date1, '/', 1)||'/0'||strtok(date1,'/', 2)
else strtok(date1, '/', 3)||'/'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
end , 'YYYY/MM/DD') as req_date
Here's another solution. It uses a regular expression to add a leading zero to any single-digit number, then standard casting to convert it to a date using existing format, then back to standard format. I have included several examples:
SELECT CAST(CAST(TD_SYSFNLIB.REGEXP_REPLACE('4/1/2015','(?<!\d)(\d)(?!\d)','0\1',1,0,'i') AS DATE FORMAT 'MM/DD/YYYY') AS DATE FORMAT 'YYYY-MM-DD');
SELECT CAST(CAST(TD_SYSFNLIB.REGEXP_REPLACE('4/14/2015','(?<!\d)(\d)(?!\d)','0\1',1,0,'i') AS DATE FORMAT 'MM/DD/YYYY') AS DATE FORMAT 'YYYY-MM-DD');
SELECT CAST(CAST(TD_SYSFNLIB.REGEXP_REPLACE('12/1/2015','(?<!\d)(\d)(?!\d)','0\1',1,0,'i') AS DATE FORMAT 'MM/DD/YYYY') AS DATE FORMAT 'YYYY-MM-DD');
It looks like you're providing the format you want, instead of the format you've got. Try this instead:
cast(RSA_dt as date format 'MM/DD/YYYY')
If you aren't using TPT, then you're stuck playing some awful substring games.
SELECT
SUBSTR(chardate,INSTR(chardate,'/',1,2)+ 1,4) AS theYear,
'00' || SUBSTR(chardate,1,INSTR(chardate,'1',1,1)-2) AS theMonth,
'00' || SUBSTR(chardate,INSTR(chardate,'/',1,1)+ 1,INSTR(chardate,'/',1,2) - INSTR(chardate,'/',1,1)-1) AS theDate,
CAST (theYear || '-' || SUBSTRING(theMonth,LENGTH(theMonth) -1,2) || '-' || SUBSTR(theDate,LENGTH(thedate)-1,2) AS DATE) AS ItsADate
FROM
<yourtable>
Really ugly, but it should work.
This should work.
Select '1/2/2014' as date1,
TO_CHAR(TO_DATE (
case
when strtok(date1, '/', 2) between 1 and 9 then strtok(date1,'/', 3)||'/0'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
else strtok(date1, '/', 3)||'/'||strtok(date1, '/', 1)||'/'||strtok(date1,'/', 2)
end , 'YYYY/MM/DD'), 'YYYY/MM/DD') as "YYYY/MM/DD"
This will work, though not pretty. Specifically converting M/D/YYYY to YYYYMMDD
select substr(YOURDATE,-4,4) ||
substr('00'||SUBSTR(YOURDATE,1,to_number(regexp_instr(YOURDATE,'\/'))-1),-2,2) ||
case when substr(YOURDATE,2,1) = '/' then
case when substr(YOURDATE,4,1) = '/' then
'0' || substr(YOURDATE,3,1)
else substr(YOURDATE,3,2)
end
else case when substr(YOURDATE,5,1) = '/' then
'0' || substr(YOURDATE,4,1)
else substr(YOURDATE,4,2)
end
end as NEWDATE
from YOURTABLE