Convert YYYYMMDD date format and Calculate Industry average by date - sql

i connected using
proc sql;
connect to odbc as odbc("......");
create table work.market as select distinct * from connection to odbc(
select distinct C.Product#, A.county, B.DT, profit2, Rev2)
From Mtable.duv A, Ttable.duv B, otable C
Where B.Product# = C.Product#
and B.Product# = A.Product#
and B.Dt = C.Dt
and B.dt between A.dt_start and dt_end
and B.dt between 20140331 and 20170630
);
disconnect from odbc;
quit;
data work.smallmarket;
set work.market;
where country=Nigeria;
NetMargin=profit2/Rev2;
keep Product# NetMargin DT;
run;
1) if DT is my date, how do I change the date format from YYYYMMDD to a SAS date format like 01Jan1960? When I run the above I get my data but the dates come out as 20170630 for example. How can i convert by date column to show in the format 30Jun2017. I posted how I got my initial data set "work.market" just in case that is part of the issue. Sorry can't post the log. Can you please help?

If you want to convert to a SAS date format, you have two places to do that.
First, you can do it in the create table statement; that is a SAS statement, not a SQL Server/whatever statement.
proc sql;
connect to odbc as odbc("......");
create table work.market as select Product#, county, dt format=date9.,profit2, rev2
from connection to odbc(
select distinct Product#, county, DT, profit2, Rev2);
The second place you can do it is in the data step following.
data work.smallmarket;
set work.market;
where country=Nigeria;
format dt date9.;
NetMargin=profit2/Rev2;
keep Product# NetMargin DT;
run;

Related

Big Query Multiple Date Format

I have a table that have multiple date format on big query table. The Date format is followed:
(please note, this is coming from staging table so the data type is defaulted as string type.
mm/dd/yyyy
yyyy-mm-dd
I'm trying to standardized date format to yyyy-mm-dd. Here is the query as followed:
select calendar_date,
FORMAT_DATE('%Y-%m-%d',safe_cast(calendar_date as date))
FROM `calendar_dates.table`
The result that came out as null
please let me know if there is another way to solve this.
Use below
SELECT
calendar_date,
COALESCE(SAFE.PARSE_DATE('%Y-%m-%d', calendar_date), SAFE.PARSE_DATE('%d/%m/%Y', calendar_date))
FROM `calendar_dates.table`
The below query, that uses safe.parse_date seems to work for me:
WITH stg AS (
SELECT "9/9/2001" AS input_date
UNION ALL
SELECT "2021-01-01" AS input_date)
SELECT
CASE
WHEN safe.parse_DATE("%Y-%m-%d", input_date) IS NULL THEN
safe.parse_DATE("%d/%m/%Y", input_date)
ELSE safe.parse_DATE("%Y-%m-%d",input_date)
END AS output_date
FROM
stg
The table
becomes:
The logic is that: BQ tests one format and if it cannot make any sense of it, it tests the other format.
If none of them work the result is NULL.

WHERE statement in SAS EG for getting the prior month of a dataset?

This is actually something I want to type into query builder in SAS EG. I am trying to filter down a data set that has dates like this:
SEP2021
AUG2021
JUL2021
etc…
I’m trying to use query builder to filter it with a WHERE statement. I want the table to have only the results dated for last month. So running it now should give SEP2021, and running it next month would give OCT2021, etc…
How can I do this with a WHERE statement?
Use intnx(). Assuming that all the dates start on the first of the month:
where date = intnx('month', today(), -1, 'B');
If they don't:
where intnx('month', date, 0, 'B') = intnx('month', today(), -1, 'B');
You can use the INTCK function to compute the number calendaring intervals between two dates.
Example:
data have;
input datestring $; datalines;
SEP2021
AUG2021
JUL2021
run;
proc sql;
create table want as
select * from have
where intck('month',input(datestring,monyy7.),today()) = 1
;
Here is the answer from KurtBremser in SAS communities, this worked for me! I did not realize what format I had converted the character value into. PROC CONTENTS revealed my values were Numeric, format DTDATE9.
Full thread here: https://communities.sas.com/t5/SAS-Enterprise-Guide/How-can-PROC-SQL-return-only-results-from-the-previous-month/m-p/774523
Solution below:
“
So it IS a datetime value, not a date. You need to use DATEPART to extract the date from it:
data have;
input date_column datetime19.;
format date_column dtdate9.;
datalines;
01sep2021:01:02:03
01oct2021:04:05:06
;
proc contents data=have;
run;
proc sql;
select *
from have
where datepart(date_column) = intnx('month',today(),-1,'b');
quit;
Partial result:
# Variable Typ Länge Ausg.Format
1 date_column Num 8 DTDATE9.
date_column
01SEP2021
“

Having Troubling Filtering Records Down Using Data Statements in PROC SQL & Teradata

Within proc sql I wish to filter my results via date ranges, and I keep getting errors. My date variables are DATE8 & the format is 04JUL1776.
I tried adding some inputs around the specific dates in the code. That did not yield anything.;
proc sql noprint;
%tdconnectTo;
create table ptemp.DL2_2018_IDS as
select * from connection to Teradata (
select distinct
PERS_ID
, REC_EFF_DT
, REC_TERM_DT
from oeauacbrgdlp1.DV_DIM_MBR
where PERS_ID is not null
and REC_EFF_DT <= '31DEC2018'd and REC_TERM_DT >= '01JAN2018'd
order by PERS_ID
);
disconnect from teradata;
quit;
If you are using pass-through SQL, then you need to supply the values in a form acceptable to the database. For a SQL date literal:
REC_EFF_DT <= date'2018-12-31' and REC_TERM_DT >= date'2018-01-01'
or if you really need to supply a string value in SAS DATE9 form for some reason, you should explicitly tell the database to convert that string to a date:
REC_EFF_DT <= to_date('31DEC2018','DDMONYYYY') and REC_TERM_DT >= to_date('01JAN2018','DDMONYYYY')
or
REC_EFF_DT <= CAST('31DEC2018' AS DATE FORMAT'DDMMMYYYY') and REC_TERM_DT >= CAST('01JAN2018' AS DATE FORMAT'DDMMMYYYY')

How to get Number of days between two dates in SAS

I have a table named case_DataTable_d in which column name value_dt have different date values. I want get number of day difference between that date and date of today.
This is my code
proc sql noprint;
create table daystoOverdue_list as
select distinct business_object_rk , DateDiff(DAY, value_dt, Today()) as value_dt
from case_DataTable_d as tbl
where tbl.cust_field_nm eq "x_case_dte_dd"
and datepart(tbl.value_dt) < today();
quit;
I'm having errors that
Day is not any column name
function DateDiff could not be located.
DateDiff is not a valid SAS function. Try intck:
%let today=%sysfunc(date());
proc sql noprint;
create table daystoOverdue_list as
select distinct business_object_rk
, intck('DAY', datepart(tbl.value_dt), &today) as value_dt
from case_DataTable_d as tbl
where tbl.cust_field_nm eq "x_case_dte_dd"
and datepart(tbl.value_dt) < &today;
This function returns the number of interval boundaries of a given kind that lie between two dates, times, or datetime values (see documentation).

convert string dd-mm-yyyy to date yyyy-mm-dd in bigquery

I have 600 string fields in a table with format eg.,18.05.2015 and i want to convert into date 2015-05-18 in bigquery. I have tried using timestamp() and date() function but it is returning null values
In Standard SQL
SELECT PARSE_DATE('%d.%m.%Y', '18.05.2015')
the query against table will look like
SELECT PARSE_DATE('%d.%m.%Y', YourDateColumn)
FROM `YourDataset.YourTable`
Added to address 'broken' values
WITH YourTable AS (
SELECT '18.05.2015' AS dt UNION ALL
SELECT '#' AS dt
)
SELECT
CASE WHEN REGEXP_CONTAINS(dt, r'\d{2}\.\d{2}\.\d{4}')
THEN CAST(PARSE_DATE('%d.%m.%Y', dt) AS STRING)
ELSE dt
END AS new_dt
FROM YourTable
what this does is - process only values that match 18.05.2015 format and leaves any other untouched
I have multiple date columns with 600 records
Making FINAL attempt to interpret your comments - but honestly, still feel like it is not what you have and you are not giving clear picture, so it is best i could make for you!
CREATE TEMPORARY FUNCTION FIX(x STRING)
RETURNS STRING AS (
CASE WHEN REGEXP_CONTAINS(x, r'\d{2}\.\d{2}\.\d{4}')
THEN CAST(PARSE_DATE('%d.%m.%Y', x) AS STRING) ELSE x END);
WITH YourTable AS (
SELECT '18.05.2015' AS dt_001, '19.05.2015' AS dt_002, '21.05.2015' AS dt_003 UNION ALL
SELECT '#' AS dt_001, '20.05.2015' AS dt_002, 'abc' AS dt_003
)
SELECT
FIX(dt_001) AS new_dt_001,
FIX(dt_002) AS new_dt_002,
FIX(dt_003) AS new_dt_003
FROM YourTable
you can update your all the string fields from dd.mm.yyy to yyyy-mm-dd format using following query.
update TABLE_NAME
set FIELD_NAME = concat(SUBSTRING(FIELD_NAME,-4),'-',SUBSTRING(FIELD_NAME,-7,2),'-',SUBSTRING(FIELD_NAME,1,2))