SQL: Convert dd/mm/yyyy to yyyyQ1 - sqlite

How to convert date to financial quarters:
3/31/2018 to 2018q1
I pulled a dataset from the FDIC website. Their date format is currently dd/mm/yyyy.
I am interested in creating a Scatter Plot/Bubble Chart using Gapminder.
However Gapminder needs each date to be converted to financial quarters. e.g. yyyyq1, yyyyq2, yyyyq3, or yyyyq4. e.g. 20017q1, 20017q2, 20017q3, or 2017q4.
This query needs to convert the date to financial quarters, but doesn't already do so. What needs to be added to convert "repdte" output dd/mm/yyyy to yyyyq1?
SELECT
PCR.name,
PCR.repdte as Quarter,
PCR.idlncorr as NetLoansAndLeasesToCoreDeposits,
CAST(LD.IDdeplam as int) as DepositAccounts$GreaterThan$250k
from All_Reports_20180630_Performance_and_Condition_Ratios as PCR
join
'All_Reports_20180630_Deposits_Based_on_the_$250,000_Reporting_Threshold'
as LD on PCR.cert = LD.cert
UNION ALL
SELECT
PCR.name,
PCR.repdte as Quarter,
PCR.idlncorr as NetLoansAndLeasesToCoreDeposits,
CAST(LD.IDdeplam as int) as DepositAccounts$GreaterThan$250k
FROM All_Reports_20180331_Performance_and_Condition_Ratios as PCR
JOIN
'All_Reports_20180331_Deposits_Based_on_the_$250,000_Reporting_Threshold'
as LD on PCR.cert = LD.cert
What I currently have
Quarter
03/31/2018
The format that Gapminder needs to render the Bubble Chart:
ReportDate
2009q1

I believe that using
substr(PCR.repdte,7,4)||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER)
will convert the date for you.
For example, consider the following :-
DROP TABLE IF EXISTS PCR;
CREATE TABLE IF NOT EXISTS PCR (repdte);
INSERT INTO PCR VALUES('01/31/2009'),('02/31/2009'),('03/31/2009'),('04/31/2009'),('05/31/2009'),('06/31/2009'),('07/31/2009'),('08/31/2009'),('09/31/2009'),('10/31/2009'),('11/31/2009'),('12/31/2009');
SELECT PCR.repdte,
substr(PCR.repdte,7,4)||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER) FROM PCR;
Which results in :-
Additional
Re comment :-
It works. However, I'm getting an output of '018q2' instead of
'2018q2'. What would I change to add a '2' to '018q2'?
This would appear to be due to the date have a variable length day part, that is if the day part is less then 10 then it is a single numeric rather than being padded with 0 and two numerics when 10 or more.
The following could be used :-
replace(substr(PCR.repdte,6),'/','')||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER)
this works by taking the year from from the 6th character and removing the / if it exists, consider the following
:-
DROP TABLE IF EXISTS PCR;
CREATE TABLE IF NOT EXISTS PCR (repdte);
INSERT INTO PCR VALUES('01/31/2009'),('02/1/2009'),('03/31/2009'),('04/31/2009'),('05/1/2009'),('06/31/2009'),('07/31/2009'),('08/1/2009'),('09/31/2009'),('10/31/2009'),('11/31/2009'),('12/31/2009');
SELECT PCR.repdte,
substr(PCR.repdte,7,4)||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER), -- OLD
replace(substr(PCR.repdte,6),'/','')||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER) -- MODIFIED
FROM PCR;
Which results in :-

Related

Creating datetime data on hour frequency by using date and hour column in integer type in Hive

I have a table including date column and hour column which is an integer type column varying from 0 to 24. I need to combine these two fields and create an hourly composite datetime field.
However, I was able to create that kind of variable by using || and cast. But I am unable to transform this code to Hive editor syntax. Can you help me with this problem
SQL Code:
CAST(CAST(CAST(DATE_OF_TRANSACTION AS FORMAT 'yyyy-mm-dd') AS VARCHAR(11))||' '||CAST(CAST( BasketHour AS FORMAT '99:') AS VARCHAR(10))||'00:00' AS TIMESTAMP(0)) Date_Time
Thank you very much
For example like this:
cast(concat(DATE_OF_TRANSACTION, ' ', lpad(BasketHour ,2,0),':00:00.0' ) as timestamp)

Apache Drill: Group by week

I tried to group my daily data by week (given a reference date) to generate a smaller panel data set.
I used postgres before and there it was quite easy:
CREATE TABLE videos_weekly AS SELECT channel_id,
CEIL(DATE_PART('day', observation_date - '2016-02-10')/7) AS week
FROM videos GROUP BY channel_id, week;
But it seems like it is not possible to subtract a timestamp with a date string in Drill. I found the AGE function, which returns an interval between two dates, but how to convert this into an integer (number of days or weeks)?
DATE_SUB may help you here. Following is an example:
SELECT extract(day from date_sub('2016-11-13', cast('2015-01-01' as timestamp)))/7 FROM (VALUES(1));
This will return number of weeks between 2015-01-01 and 2016-11-13.
Click here for documentation

Compare date columns

I need to retrieve the rows that service_date is greater than prod_date.
The data type for prod_date is VARCHAR(10) (2/20/2014 for example) and the data type for service_date is DATE (YYYYMMDD). If I query service_date using "select service_date from service where service_date ='20140201'", the result is showing "2/1/2014" in the result grid. However, it does not work in the query below when I convert service_date to varchar to compare with prod_date. It pulls out all the rows instead of the ones that have greater service_date.
SELECT P.PROD_ID, P.PROD_DESC, S.PROD_ID, S.SERVICE_LOC
FROM PRODUCT P
INNER JOIN SERVICE S
WHERE P.PROD_ID = S.PROD_ID
AND CAST(S.SERVICE_DATE AS VARCHAR(10)) >= P.PROD_DATE
I suggest you use date ordering instead of string/varchar ordering if possible for simplicity and since its [ probably ] closer to what your interested in and less likely to confuse
For example
'01/02/2014' >= '04/01/2013' -- if these are dates or cast to dates
but
'01/02/2014' < '04/01/2013' -- if these are strings
So to keep things simple, it makes sense to cast PROD_DATE to a date when comparing these two fields like :
SELECT P.PROD_ID, P.PROD_DESC, S.PROD_ID, S.SERVICE_LOC
FROM PRODUCT P
INNER JOIN SERVICE S
WHERE P.PROD_ID = S.PROD_ID
AND S.SERVICE_DATE >= cast(P.PROD_DATE as date format 'DD/MM/YYYY')
;
if theres any doubts on prod_dates quality as valid dates can check the conversion on all dates first ( before running/adjusting above )
This isn't 100% error proof given your date is character and could have unexpected values. It does show how you can append a leading 0 to the month value and cast it to a date when the month is determined to be a single digit based on the location of the / in the second position of the PROD_DATE value for a given row.
SELECT CASE WHEN POSITION('/' IN TRIM(P.PROD_DATE)) = 2
THEN CAST('0'|| TRIM(P.PROD_DATE) AS CHAR(10)) AS DATE FORMAT 'MM/DD/YYYY')
ELSE CAST(P.PROD_DATE AS DATE FORMAT 'MM/DD/YYYY')
END AS PROD_DATE_
FROM PRODUCT P;

Date format in SAS

I have a SAS code that I need to convert into R.
My SAS code is something like this -
proc sql;
create table data as
select a.*,b.qty from Sales as a inner join Units as b
on a.id=b.id and put(a.date,yymmn6.)=put(c.date,yymmn6.)
quit;
I know that put(a.date,yymmn6.) converts the date into a SAS date value. But what does a.date become after this function? If date=01jan2012, put(a.date,yymmn6.) makes it as some SAS value that represents 201201 or 20120101? i.e. the SAS value created will stand for the whole date or just the year and mon of the date?
Currently, I am writing the R code for this as -
data <- sqldf("select a.*,b.qty from Sales as a inner join Units as b
on a.id=b.id and a.date=c.date")
Should I be doing it as -
Sales$date <- as.yearmon(Sales$date)
Units$date <- as.yearmon(Units$date)
data <- sqldf("select a.*,b.qty from Sales as a inner join Units as b
on a.id=b.id and a.date=c.date")
I don't have access to SAS and hence, I cannot try this out on a sample data. Any help would be great. Thanks!
put(a.date,yymmn6.) converts a numeric date value to a character value stored as yyyymm (e.g. 201201). Therefore the join condition is matching all dates where the month and year are the same, but not necessarily the day.
I'm not sure of the best way of achieving this in R, but you seem to have some ideas on this.
Hope this helps.
When you use put(a.date,yymmn6.) the output of that function is a character. Put takes a numeric input and format and outputs the formatted numeric value as character. input function does the opposite.
data mydata;
sas_numeric_date = "01jan2012"d;
sas_yyyymm_char_date = put(sas_numeric_date, yymmn6.);
sas_yyyymm_numeric_date = input(sas_yyyymm_char_date, yymmn6.);
output;
sas_numeric_date = "29Feb2012"d;
sas_yyyymm_char_date = put(sas_numeric_date, yymmn6.);
sas_yyyymm_numeric_date = input(sas_yyyymm_char_date, yymmn6.);
output;
format sas_numeric_date sas_yyyymm_numeric_date date9.;
run;
sas_numeric_date sas_yyyymm_char_date sas_yyyymm_numeric_date
01Jan2012 201201 01Jan2012
29Feb2012 201202 01Feb2012
So, when you apply the yymmn6. as informat on sas_yyyymm_char_date - which itself is in yyyymm format, the resulting value is numeric and day part in the date defaults to the first day of the month as shown above.

Get RowCount With Date Comparasion in SSRS

I am new to SSRS.
I have a dataset, my dataset brings data from a stored procedure.
one of the parameters of my sp is StartDate and another one is EndDate. Their type is datetime
And the table has a dateTime Column called Date.
I have two gauges and I wanna bind integer values to my gauges.
First one is the count of rows where Date < DateAdd(DateInterval.Hour,24,StartDate)
and te second is count of rows where Date > DateAdd(DateInterval.Hour,24,StartDate)
How will I write the exact script. Whatever I wrote is not working.
I appreciate any help, thanks.
You need to set the gauge Pointer value as something like:
=Sum(IIf(DateDiff(DateInterval.Day, Parameters!StartDate.Value, Fields!Date.Value) >= 1
, 1
, 0))
This is counting rows where the time difference is less than a day compared to the parameter StartDate. Just change it slightly to get those where the difference is at least a day:
=Sum(IIf(DateDiff(DateInterval.Day, Parameters!StartDate.Value, Fields!Date.Value) >= 1
, 0
, 1))
Worked fine for me in a quick test:

Resources