BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
dkassis
Calcite | Level 5

Hi,

 

Getting an error when using the coalesce function below that works with standard ANSI SQL. Any ideas how to modify?

 


proc sql;
create table xxxxxxxxxxx as

select lp.epoch_interval_time,
divide ( mod ( lp.epoch_interval_time - 7*3600 , 86400 ), 3600 ) as intv_hr,
divide ( mod ( lp.epoch_interval_time - 7*3600 , 86400 ), 3600 )+ 1 as intrvl_24hr_ending,
lp.local_interval_time,
lp.utc_interval_time,
lp.lp_value,
lp.validation_status,
lp.lp_interval_length,
sdps.udc_id as sp
from xxxxxxxxxxxxxxx
join xxxxxxxxxxxxxxxxxx on lp.channel_id = chn.channel_id
and chn.channel_type = 'Interval Data'
and chn.physical_channel_no in (1,11,21)

join xxxxxxxxxxxxx on chn.sdp_id = sdps.sdp_id
where lp.utc_interval_yr_mth in (201910,201909)
AND (lp.utc_interval_time >= chn.start_date AND lp.utc_interval_time <= COALESCE(chn.end_date, CAST('2099-01-01 01:00:00' as TIMESTAMP)))
AND sdps.meter_id = chn.meter_id
AND (lp.utc_interval_time >= sdps.start_date AND lp.utc_interval_time <= COALESCE(sdps.end_date, CAST('2099-01-01 01:00:00' as TIMESTAMP)))

 

Thanks,

Dan

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

Are you now just showing us or do you still not know how to fix the issue.

 

From the log you've posted: 

Always show the very first error in the log. You haven't posted the code which causes the first error.

 

For the 2nd error where you also show the code: You haven't commented out correctly.

What you've done:

COALESCE(sdps.end_date,'01jan2099:01:00:00'dt /*CAST('2099-01-01 01:00:00'*/ as TIMESTAMP))

How it should look like:

COALESCE(sdps.end_date,'01jan2099:01:00:00'dt /*CAST('2099-01-01 01:00:00' as TIMESTAMP)*/)

 

View solution in original post

10 REPLIES 10
Reeza
Super User
Is it COALESCE or CAST() that's causing the issue? SAS doesn't have a CAST function, you would use PUT() or INPUT() there depending on what you're trying to do. The actual error would indicate where the issue is.
ChrisNZ
Tourmaline | Level 20

cast('2099-01-01 01:00:00' as TIMESTAMP)

is written

'01jan2099:01:00:00'dt

in SAS.

 

Please look at your log messages more carefully, I suspect SAS complained loudly about your calling a non-existing function.

 

 

 

dkassis
Calcite | Level 5

I suspect this is a cast issue.  Here is the error I am getting:

 

__
22
202
ERROR 22-322: Syntax error, expecting one of the following: !,
!!, &, ), *, **, +, ',', -, /, <, <=, <>, =, >,
>=, ?, AND, BETWEEN, CONTAINS, EQ, EQT, GE, GET,
GT, GTT, IN, IS, LE, LET, LIKE, LT, LTT, NE, NET,
NOT, NOTIN, OR, ^, ^=, |, ||, ~, ~=.

ERROR 202-322: The option or parameter is not recognized and
will be ignored.

47 AND sdps.meter_id = chn.meter_id
48 AND (lp.utc_interval_time >= sdps.start_date AND
48 ! lp.utc_interval_time <=
48 ! COALESCE(sdps.end_date,'01jan2099:01:00:00'dt
48 ! /*CAST('2099-01-01 01:00:00'*/ as TIMESTAMP))
__
22
202
ERROR 22-322: Syntax error, expecting one of the following: !,
!!, &, ), *, **, +, ',', -, /, <, <=, <>, =, >,
>=, ?, AND, BETWEEN, CONTAINS, EQ, EQT, GE, GET,
GT, GTT, IN, IS, LE, LET, LIKE, LT, LTT, NE, NET,
NOT, NOTIN, OR, ^, ^=, |, ||, ~, ~=.

ERROR 202-322: The option or parameter is not recognized and
will be ignored.

Patrick
Opal | Level 21

Are you now just showing us or do you still not know how to fix the issue.

 

From the log you've posted: 

Always show the very first error in the log. You haven't posted the code which causes the first error.

 

For the 2nd error where you also show the code: You haven't commented out correctly.

What you've done:

COALESCE(sdps.end_date,'01jan2099:01:00:00'dt /*CAST('2099-01-01 01:00:00'*/ as TIMESTAMP))

How it should look like:

COALESCE(sdps.end_date,'01jan2099:01:00:00'dt /*CAST('2099-01-01 01:00:00' as TIMESTAMP)*/)

 

ChrisNZ
Tourmaline | Level 20

Did you replace the cast() value as shown?

dkassis
Calcite | Level 5

Sorry for the confusion, when I commented out the cast the error went away.  

Tom
Super User Tom
Super User

Code seem over complicated, especially that mod/div stuff.  Looks like you are just trying to pull out the HOUR, after subtracting 7 hours.

proc sql;
create table xxxxxxxxxxxxxxx as
select lp.epoch_interval_time
     , hour(intnx('hour',lp.epoch_interval_time,-7)) as intv_hr
     , calculated intv_hr + 1 as intrvl_24hr_ending
     , lp.local_interval_time
     , lp.utc_interval_time
     , lp.lp_value
     , lp.validation_status
     , lp.lp_interval_length
     , sdps.udc_id as sp
from xxxxxxxxxxxxxxx lp
join xxxxxxxxxxxxxxx chn
  on lp.channel_id = chn.channel_id
 and chn.channel_type = 'Interval Data'
 and chn.physical_channel_no in (1,11,21)
join xxxxxxxxxxxxxxx sdps
  on chn.sdp_id = sdps.sdp_id
where lp.utc_interval_yr_mth in (201910,201909)
  AND lp.utc_interval_time >= chn.start_date
  AND lp.utc_interval_time <= COALESCE(chn.end_date, "01JAN2099:01:00"dt)
  AND sdps.meter_id = chn.meter_id
  AND lp.utc_interval_time >= sdps.start_date
  AND lp.utc_interval_time <= COALESCE(sdps.end_date, "01JAN2099:01:00"dt)
;
quit;

Why are some of the conditions in the WHERE clause not included into the ON clause? Like:

  AND sdps.meter_id = chn.meter_id

 

dkassis
Calcite | Level 5

To add a little more context, this data is pulling from a Hadoop platform.  I have to convert EPOCH time (integer) to readable time hence the calculation.  I am working on developing and testing a new table structure that extracts 15 minute interval data and then will roll it up to hourly and daily data in subsequent tables I am doing those steps in a series of proc means with a limited amount of data just for testing purposes. 

 

I got the code above from my ETL developer who doesn't use SAS but BDM or DB visualizer, so I have to translate to SAS.  I want to ensure all the code runs in hadoop for optimal performance so I want to make sure I use supported functions within the SAS/ACCESS engine.  

 

The above code won't run entirely in Hadoop but I have what I need for now until my developer gets back.  Thanks for all the help.

 

Thanks,

Dan

ChrisNZ
Tourmaline | Level 20

> ensure all the code runs in hadoop for optimal performance

 

Why don't you use the Hadoop code in a pass-through query then? Just an idea.

Patrick
Opal | Level 21

"I got the code above from my ETL developer who doesn't use SAS but BDM or DB visualizer, so I have to translate to SAS.  I want to ensure all the code runs in hadoop for optimal performance so I want to make sure I use supported functions within the SAS/ACCESS engine."

 

The SAS Access engines allow you to pass code directly to a database for execution (explicit pass-through). So if you've already got working Hive SQL then that's what I'd be doing: Just copy/paste this Hive SQL into the EXECUTE block.

Also: If you want everything working in Hadoop and you then want to hand-over this code for implementation not using SAS at all then I'd be using Hue or DBeaver for development of Hive SQL. 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 10 replies
  • 1804 views
  • 0 likes
  • 5 in conversation