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).
Related
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
“
I am trying to get the current month records from a table. Since this is going to be an automated monthly job, I can't give explicit values in where clause. So I am using the intnx function to get the month's start and end date. Then comparing them with the table value (date) in where clause. I tried different date formats but every time I am getting the same error: "ERROR: Expression using equals (=) has components that are of different data types."
Below is my script. What am I doing wrong?
DATA _NULL_;
CALL
SYMPUT('MonthStart',TRIM(PUT(INTNX('MONTH',TODAY(),0,'B'),ddmmyys10.)));
CALL
SYMPUT('MonthEnd',TRIM(PUT(INTNX('MONTH',TODAY(),0,'E'),ddmmyys10.)));
RUN;
%PUT &MonthStart.;
%PUT &MonthEnd.;
PROC SQL;
CREATE TABLE CURRENT_MONTH_ACTIVITY AS
SELECT * FROM MONTH_END_BASE
WHERE ACTIVITY_DATE >= '&MonthStart.' AND ACTIVITY_DATE <= '&MonthEnd.' ;
QUIT;
Thanks in advance!
You can use the INTCK function to check for when the month range from the current date to the activity date is zero.
where INTCK('MONTH', today(), activity_date) = 0;
An alternative would be to use macro to 'code-gen' directly the between points. You don't need a data step to populate a macro variable that is later used.
Example:
data have;
do activity_date = today() - 365 to today() + 365;
output;
end;
format activity_date yymmdd10.;
run;
data want;
set have;
where intck('MONTH', today(), activity_date) = 0;
run;
data want;
set have;
where activity_date
between
%sysfunc(INTNX(MONTH, %sysfunc(today()), 0, B))
and
%sysfunc(INTNX(MONTH, %sysfunc(today()), 0, E))
;
run;
I agree with Tom. Probably the variable activate_date is a numeric type with date format, then the solution is assign to MonthStart and MonthEnd a numeric value.
DATA _NULL_;
CALL SYMPUT('MonthStart',INTNX('MONTH',TODAY(),0,'B'));
CALL SYMPUT('MonthEnd',INTNX('MONTH',TODAY(),0,'E'));
RUN;
%PUT &MonthStart.;
%PUT &MonthEnd.;
PROC SQL;
CREATE TABLE CURRENT_MONTH_ACTIVITY AS
SELECT * FROM MONTH_END_BASE
WHERE ACTIVITY_DATE >= &MonthStart. AND ACTIVITY_DATE <= &MonthEnd. ;
QUIT;
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')
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;
I am trying to find a data with specific where clause of date and month but I am receiving an error can anyone help me with this?
select *
from my_data
where date BETWEEN '11-20' AND '12-15'
MS SQL Server Management Studio
I am receving an error
Conversion failed when converting date and/or time from character string
Most databases support functions to extract components of dates. So, one way of doing what you want is to convert the values to numbers and make a comparison like this:
where month(date) * 100 + day(date) between 1120 and 1215
The functions for extracting date parts differ by database, so your database might have somewhat different methods for doing this.
The conversion is failing because you are not specifying a year. If you were to specify '11-20-2015' your query would work just insert whatever year you need.
SELECT *
FROM my_data
WHERE date BETWEEN '11-20-2015' AND '12-15-2015'
Alternatively if you wanted data from that range of dates for multiple years I would use a while loop to insert information in a # table then read from that table, depending on the amount of data this could be quick or sloooowww here is an example.
DECLARE #mindatestart date, #mindateend date, #maxdatestart date
SET #mindatestart = '11-20-2010'
SET #mindateend = '12-15-2010'
SET #maxdatestart = '11-20-2015'
SELECT top 0 *, year = ' '
INTO #mydata
FROM my_data
WHILE #mindatestart < #maxdatestart
BEGIN
INSERT INTO #mydata
SELECT *, YEAR(#mindatestart)
FROM my_data
where date between #mindatestart and #mindateend
SET #mindatestart = DATEADD(Year, 1, #mindatestart)
SET #mindateend = DATEADD(Year, 1, #mindateend)
END
This will loop and insert the data from 2010-2015 for those date ranges and add a extra column on the end so you can call the data and order by year if you want like this
SELECT * FROM #mydata order by YEAR
Hopefully some part of this helps!
FROM THE COMMENT BELOW
SELECT *
FROM my_data
WHERE DAY(RIGHT(date, 5)) between DAY(11-20) and DAY(12-15)
The reason '11-20' doesn't work is because its a character string which is why you have to input it between ' ' What the Month() function does is take whatever you put between the () and convert it to an integer. Which is why you're not getting anything back using the method in the first answer, the '-Year' from the table date field is being added into the numeric value where your value is just being converted from 11-20 you can see by using these queries
SELECT MONTH(11-20) --Returns 12
SELECT MONTH(11-20-2015) -- Returns 6
SELECT MONTH(11-20-2014) -- Returns 6
Using RIGHT(Date, 5) you only get Month-day, then you date the day value of that so DAY(RIGHT(DATE, 5) and you should get something that in theory should fall within those date ranges despite the year. However I'm not sure how accurate the data will be, and its a lot of work just to not add an additional 8 characters in your original query.
Since you only care about month and day, but not year, you need to use DATEPART to split up the date. Try this:
select *
from my_data
WHERE 1=1
AND (DATEPART(m, date) >= 11 AND DATEPART(d,date) >= 20)
AND (DATEPART(m, date) <= 12 AND DATEPART(d,date) <= 15)