SQL Dates and Time Formatting - sql

got a quick question on some SQL formatting. I am struggling figuring out how to make the formatting for a table the same. The table includes about 15 years worth of data. Most of the time stamps are formatted in a similar way. They are in columns "Day" "Date" and "YT":
"Sun" "Dec 17" " 2017 11:58:00 PM"
The data from this past year is formatted to look like this:
"Jan 4 - 10:43 AM"
This string is all in one column; "Day".
I am looking for a few things. I need the format to be the same so that I can work with it. So hoping I can leave the day column blank, since it doesn't tell us what day of the week it was. I would like to move the part of the string that is the month and date into column "Date" to match the previous data. and I would like to add "2018" before the time stamp and have that value be in column "YT".
I am using DB Browser and SQLite.
I appreciate all the help. I am new to sql and python and apologize if I have missed something obvious. If there is an easy solution that I am missing, some pointing me in the right direction to read about it/figure it out myself would also be greatly appreciated.

Assuming you are using sqlite:
I created a simple table to verify the results as follows:
DROP TABLE IF EXISTS MY_TABLE;
CREATE TABLE MY_TABLE ("SOME_UNIQUE_ID" INTEGER,"Day" TEXT,"Date" TEXT,"YT" TEXT);
INSERT INTO MY_TABLE ("SOME_UNIQUE_ID","Day","Date","YT") VALUES ("1","Sun","Dec 17","2017 11:58:00 PM");
INSERT INTO MY_TABLE ("SOME_UNIQUE_ID","Day","Date","YT") VALUES ("2","Jan 4 - 10:43 AM","","");
So, after committing the previous statements, running the following query...
SELECT * FROM MY_TABLE;
returns...
SOME_UNIQUEID Day Date YT
1 Sun Dec 17 2017 11:58:00 PM
2 Jan 4 - 10:43 AM
Finally, this is the big query to get all of your records with a nicely formatted datetime column. You'll have to modify this query to match your table name and column names.
SELECT SOME_UNIQUE_ID,
datetime(FULL_DATE_STRING) AS DATETIME_FULL
FROM (
SELECT SOME_UNIQUE_ID,
coalesce(YYYY_str,"") || "-" || coalesce(MM_str,"") || "-" || coalesce(DD_str,"") || " " || coalesce(HHMMSS_str,"") AS FULL_DATE_STRING
FROM (
SELECT SOME_UNIQUE_ID,
substr(YT,0,5) AS YYYY_str,
CASE substr("Date",0,4)
WHEN 'Jan'
THEN '01'
WHEN 'Feb'
THEN '02'
WHEN 'Mar'
THEN '03'
WHEN 'Apr'
THEN '04'
WHEN 'May'
THEN '05'
WHEN 'Jun'
THEN '06'
WHEN 'Jul'
THEN '07'
WHEN 'Aug'
THEN '08'
WHEN 'Sep'
THEN '09'
WHEN 'Oct'
THEN '10'
WHEN 'Nov'
THEN '11'
WHEN 'Dec'
THEN '12'
ELSE NULL
END MM_str,
substr("Date",5,2) AS DD_str,
substr(substr(YT, 6),0,9) AS HHMMSS_str
FROM MY_TABLE
)
)
WHERE DATETIME_FULL IS NOT NULL
UNION ALL
SELECT SOME_UNIQUE_ID,
datetime(YYYYMMDD_str || " " || HHMMSS_str_mod) AS DATETIME_FULL
FROM (
SELECT SOME_UNIQUE_ID,
YYYY_str || "-" || MM_str || "-" || DD_str AS YYYYMMDD_str,
CASE AMPM_str
WHEN 'AM'
THEN HHMMSS_str
WHEN 'PM'
THEN replace(HHMMSS_str,substr(HHMMSS_str,1,2),substr(HHMMSS_str,1,2)+12)
ELSE NULL
END HHMMSS_str_mod
FROM (
SELECT SOME_UNIQUE_ID,
"2018" AS YYYY_str,
MM_str,
substr('00'||D_str,-2) AS DD_str,
HHMMSS_str,
AMPM_str
FROM (
SELECT SOME_UNIQUE_ID,
CASE substr("Day",1,3)
WHEN 'Jan'
THEN '01'
WHEN 'Feb'
THEN '02'
WHEN 'Mar'
THEN '03'
WHEN 'Apr'
THEN '04'
WHEN 'May'
THEN '05'
WHEN 'Jun'
THEN '06'
WHEN 'Jul'
THEN '07'
WHEN 'Aug'
THEN '08'
WHEN 'Sep'
THEN '09'
WHEN 'Oct'
THEN '10'
WHEN 'Nov'
THEN '11'
WHEN 'Dec'
THEN '12'
ELSE NULL
END MM_str,
rtrim(substr("Day",5,2)) AS D_str,
substr("Day",-8,5) || ":00" AS HHMMSS_str,
substr("Day",-2,2) AS AMPM_str
FROM MY_TABLE
)
)
)
WHERE DATETIME_FULL IS NOT NULL
;
Returns:
SOME_UNIQUE_ID DATETIME_FULL
1 2017-12-17 11:58:00
2 2018-01-04 10:43:00
From here, you can get DATETIME_FULL in any format you'd like, see
https://www.sqlite.org/lang_datefunc.html. Also, python has many ways to work with datetime data which you can search on your own.

Related

How to convert/extract from YYYYMM to year and name of Month? Teradata SQL

So i got the date format in YYYYMM (eg. 201910 for Oct 2019), and what I want to have is 2019 and October (in full month name). Year number is easy, but to get the month name is a bit challenging.
In my data Calendar_Year_Month is the available field in the format of INT eg. 201910. I firstly converted to STRING and then adding just a random day 01 to become 20191001, then casting it to DATE format as Year_Month_Date.
CAST(Calendar_Year_Month*100+01 AS VARCHAR(8)) AS Year_Month,
CAST(Year_Month AS DATE FORMAT 'YYYYMMDD')AS Year_Month_Date,
I tried to use `TO_DATE(Year_Month_Date,'Month') to get the Month name, however, it seems not working.
Any other options to achieve?
You were close:
CAST the int to a date and then apply TO_CHAR:
To_Char(Cast((Calendar_Year_Month-190000) * 100 + 1 AS DATE), 'Month') AS cal_month
Extracting the year is simple:
Calendar_Year_Month/100 as cal_year
Have you tried:
1.
With to_char
to_char(Year_Month_Date, 'Month')
2.
You can always add a CASE WHEN for all 12 months if you do not find any simpler solution...
3.
With format:
Year_Month_Date(format 'MMMM')
Or for the combination with year:
Year_Month_Date(format 'MMMMBYYYY')
Assuming your Calendar_Year_Month is well-formatted, here's one way to do it:
SELECT
SUBSTRING(CAST(Calendar_Year_Month AS CHAR(6)) FROM 1 FOR 4) AS MyYear -- Extract year
CASE SUBSTRING(CAST(Calendar_Year_Month AS CHAR(6)) FROM 5 FOR 2) -- Extract month
WHEN '01' THEN 'January'
WHEN '02' THEN 'February'
WHEN '03' THEN 'March'
WHEN '04' THEN 'April'
WHEN '05' THEN 'May'
WHEN '06' THEN 'June'
WHEN '07' THEN 'July'
WHEN '08' THEN 'August'
WHEN '09' THEN 'September'
WHEN '10' THEN 'October'
WHEN '11' THEN 'November'
WHEN '12' THEN 'December'
END CASE AS MyMonth
FROM MyTable
Another option is to try and convert Calendar_Year_Month to a DATE and use TO_CHAR():
SELECT
CAST(CAST(Calendar_Year_Month AS CHAR(6)) AS DATE FORMAT 'YYYYMM') AS MyDate,
TO_CHAR(MyDate,'Month') AS MyMonth,
TO_CHAR(MyDate,'YYYY') AS MyYear
FROM MyTable
I don't have a TD system to test, but give it a try and let me know.

SQL: Query column (string) as date

Assume I have a few columns in a database: id, date_added, tag
`20134` | `February 07, 2019` | `New`
`40323` | `February 09, 2019` | `New`
I want to run a query with a filter based on date_added:
SELECT * FROM table
WHERE date_added > 'February 08, 2019'
How would I do this? I saw you can convert strings to date objects, but wasn't sure if that is possible inside a WHERE filter.
Any help is appreciated!
Edit: I am using SQLite
You chose a format for the date_added column, that is not comparable.
SQLite is not that flexible with dates, which are in fact Text.
So in this case you need to extract the date parts piece by piece and create a comparable date:
select *
from tablename
where
substr(date_added, instr(date_added, ',') + 2) ||
case substr(date_added, 1, instr(date_added, ' ') - 1)
when 'January' then '01'
when 'February' then '02'
when 'March' then '03'
when 'April' then '04'
when 'May' then '05'
when 'June' then '06'
when 'July' then '07'
when 'August' then '08'
when 'September' then '09'
when 'October' then '10'
when 'November' then '11'
when 'December' then '12'
end ||
substr(date_added, instr(date_added, ' ') + 1, 2) > '20190208'
See the demo
Look, I do not know what database engine you're working with, but in case it's an Sql server, you can do the following:
in the following query it is not necessary to cast the date_added column if it is of the date type, in case it is of the string type, you can also cast it cast (date_add as date).
SELECT * FROM table
WHERE date_added > cast('2019-01-01' as date)
NOTE: it is very important that if they are going to handle dates as string type, they must have a valid format, in Sql Server the dates are saved by default in yyyy-MM-dd -2019-02-10.
If you want to convert the date in another format you can use the convert function

Sql query get month from datetime

i've got a DB with invoices and datetime that they were created, i want to have a New columm with the name of The month according to The date of each invoice. I mean if The date is 2013-01-15, i would like to have " january" on The New columm.
Thanks in advance, i've few knowledge about sql.
If your database is MySQL, try:
DATE_FORMAT(date, '%M')
For MS SQL Server use
SELECT DATENAME(MONTH,invoiceDate)
In Oracle:
TO_CHAR(date, 'Month')
Extract the month from the datetime object and then use it in a CASE statement.
Build upon this
select
case strftime('%m', date('now'))
when '01' then 'January'
when '02' then 'Febuary'
when '03' then 'March'
when '04' then 'April'
when '05' then 'May'
when '06' then 'June'
when '07' then 'July'
when '08' then 'August'
when '09' then 'September'
when '10' then 'October'
when '11' then 'November'
when '12' then 'December' else '' end
as month
I would suggest copying the schema of your table, adding another column for the month. Then using the following statement.
INSERT INTO TABLE newTable (col1, col2, col3, ..., colLast, colMonth)
SELECT col1, col2, col3, ..., colLast,
case strftime('%m', date('now'))
when '01' then 'January'
when '02' then 'Febuary'
when '03' then 'March'
when '04' then 'April'
when '05' then 'May'
when '06' then 'June'
when '07' then 'July'
when '08' then 'August'
when '09' then 'September'
when '10' then 'October'
when '11' then 'November'
when '12' then 'December' else '' end
as colMonth
FROM oldTable;
Then
drop table oldTable;
Then
Some alter to change the name of the new table to the name of the old table.

Clean Dirty data in SQL

In a data base the data is dirty, "date" is the Database is saved as a string and in different different formats.
I want to clean the data base and put it in a new database in which date would be in DATE sql format.
But the issue is that date in dirty date is in different formats
e.g.
14 sept 2012
14 SEPTEMBER 2012
14th sept 2012
14th sept 12
14 sept 12
etc
How to convert every date in single sql DATE format??
Assuming all date are later than or year 2000 and two digits for date and at least 3 letters for month, try this. SQL Fiddle here
SELECT CONVERT (DATE, '20' + right(mydate,2)+
CASE substring(mydate,charindex(' ', mydate,0)+ 1,3)
when 'jan' then '01'
when 'feb' then '02'
when 'mar' then '03'
when 'apr' then '04'
when 'may' then '05'
when 'jun' then '06'
when 'jul' then '07'
when 'aug' then '08'
when 'sep' then '09'
when 'oct' then '10'
when 'nov' then '11'
when 'dec' then '12'
else 'error' end +
left(mydate,2))
FROM t
NOTE: Solution is based on the given data samples
try this:
create table tmp_date(col1 varchar(100));
insert into tmp_date
VALUES('14 sept 2012'),('14 SEPTEMBER 2012'),('14th sept 2012'),('14th sept 12'),('14 sept 12')
select convert(datetime,left(col1,2)+'-'+lower(SUBSTRING(col1,CHARINDEX(' ',col1,1)+1,3))+'-'+ltrim(rtrim(reverse(LEFT(REVERSE(col1),CHARINDEX(' ',REVERSE(col1),1)))))) from tmp_date

SQL Server adding a record record manually to a view

I have a view which contains the data seen in the image below.
The view is showing me how many working days are available in each month for the current financial year taking away any school/bank holidays.
As the month of August has zero days available it has excluded this month from the view.
As the total number of days available will always be zero for the month of August, then it seems acceptable to hardcode the SQL to always have 0 for August, and also an April-August record which will be the same as April-July.
What would be the best way to add these 2 records, and where about in the code should it be placed see example of code layout:
see link (answered question) for layout of code:
SQL populate total working days per month minus bank holidays for current financial year
For my answer, I will assume you have a view vDays with columns that match your screen shot: period, availabledays, year.
To append any zero-day periods to your results whatever month may have zero (which will cater for August and any other month that happens to have zero days), you can extend your view like this:
WITH Mths (Mth) AS (
SELECT 'January'
UNION SELECT 'February'
UNION SELECT 'March'
UNION SELECT 'April'
UNION SELECT 'May'
UNION SELECT 'June'
UNION SELECT 'July'
UNION SELECT 'August'
UNION SELECT 'September'
UNION SELECT 'October'
UNION SELECT 'November'
UNION SELECT 'December'
UNION SELECT 'April - January'
UNION SELECT 'April - February'
UNION SELECT 'April - March'
UNION SELECT 'April - May'
UNION SELECT 'April - June'
UNION SELECT 'April - July'
UNION SELECT 'April - August'
UNION SELECT 'April - September'
UNION SELECT 'April - October'
UNION SELECT 'April - November'
UNION SELECT 'April - December'
), Years (Year) AS (
SELECT DISTINCT year
FROM vDays
), ZeroPeriods (Mth, Years) AS (
SELECT Mth, Year
FROM Mths, Years
), JoinedData (Mth, AvailableDays, Year) AS (
SELECT Mth, 0, Years
FROM ZeroPeriods
UNION ALL
SELECT period, availabledays, year
FROM vDays
), GroupedData (Mth, AvailableDays, Year) AS (
SELECT Mth, SUM(AvailableDays), Year
FROM JoinedData
GROUP BY Mth, Year
)
SELECT *
FROM GroupedData
ORDER BY Year, CASE UPPER(LEFT(Mth, 3))
WHEN 'JAN' THEN 1 WHEN 'FEB' THEN 2 WHEN 'MAR' THEN 3
WHEN 'APR' THEN 4 WHEN 'MAY' THEN 5 WHEN 'JUN' THEN 6
WHEN 'JUL' THEN 7 WHEN 'AUG' THEN 8 WHEN 'SEP' THEN 9
WHEN 'OCT' THEN 10 WHEN 'NOV' THEN 11 ELSE 12 END;
I have split this out into lots of separate queries, although some could be merged into sub queries, but doing it like this makes it a lot clearer to understand.
Would this give you your desired result set?
SELECT Period, DaysAvailable, Year FROM YOURVIEW
UNION ALL
SELECT DISTINCT 'April-August', DaysAvailable, Year FROM YOURVIEW where Period = 'April-July'
UNION ALL
SELECT DISTINCT 'August', 0, YEAR FROM YOURVIEW