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

I cannot get this query to run.  I've tried a lot of variations on this query - mostly trying either the WITH clause or an inline query.  I can use the SQL passthrough to DB2 with simpler queries, so I've left it out of the examples.  I've googled the error message, DB2 "WITH Clause", "common table expression", "CTE", and various combinations, and none of the dozens of results had anything that helps me resolve the issue.  I've also tried the inner query alone - that works.  I've tried these variants in another query tool, and have gotten the same results.  I know that means it's not a SAS problem, but I'm hoping someone can help, or point me to any useful documentation.

 

WITH clause VERSION:

   WITH inner_query AS 

          (SELECT oc.clm_cd, p.prod_ser_no, p.bld_date, p.vin,
                      p.in_srvc_date, p.in_srvc_trk_mlg,
                      year(p.in_srvc_date) as in_service_year,
                      case when p.prod_type_cd = 'ENGINE'
                              then p.prod_ser_no else '' end as eng_serial_number,
                      case when p.prod_type_cd = 'ENGINE'
                             then p.prod_mdl_cd else '' end as eng_model,
                      p.prod_mdl_cd, p.voc_cd,
                      p.prod_make_cd, p.prod_mdl_cd as fllc_internal_model,
                      p.prod_fam_cd, p.chass_mdl_cd, oc.flt_cd,
                      oc.flt_name, oc.fail_date, oc.trk_mlg_amt,
                     case when cfa.new_maj_comp_ser is not null
                             then oc.trk_mlg_amt else 0 end as eng_repl_mileage,
                     case when cfa.new_maj_comp_ser is not null
                             then oc.fail_date else '12-31-2999' end as eng_repl_date
           FROM wty_ddc.claims_fact_ddc_v oc
           INNER JOIN wty_ddc.product_dim_v p
           ON oc.prod_id = p.prod_id
           INNER JOIN wty_ddc.claims_fact_attr_ddc_v cfa
           ON cfa.clm_id = oc.clm_id
           WHERE trk_mlg_amt is not null and trk_mlg_amt > 0
                     and prod_type_cd in ('ENGINE','CHASSIS')
)

   SELECT  clm_cd, prod_ser_no, bld_date, vin,  /*POST EDITED TO REMOVE TABLE ALIAS Q. from clm_cd */
            in_srvc_date, in_srvc_trk_mlg,
            in_service_year,
            prod_mdl_cd, voc_cd,
            prod_make_cd, fllc_internal_model,
            prod_fam_cd, chass_mdl_cd, flt_cd,
            flt_name, fail_date, trk_mlg_amt,
           eng_repl_mileage,
           eng_repl_date,
           max(eng_serial_number) OVER PARTITION BY (vin) as eng_serial_number,
           max(eng_model) OVER PARTITION BY (vin) as eng_model
     FROM inner_query
     ORDER BY vin, fail_date desc;

 

ERROR: CLI describe error: [IBM][CLI Driver][DB2/AIX64] SQL0104N  An unexpected token "clm_cd, prod_ser_no,
       bld_date, vin, in_sr" was found following "il_date desc) select".  Expected tokens may include: 
       "<space>".  SQLSTATE=42601

(My interpretation is that it objects to the outer query.  If I remove the columns list with "select * from inner_query" leaving the order by clause, THIS DOES WORK.  But there's no need for the WITH clause in that case - it's superfluous.  Anyway, part of the work I want to do here requires that PARTITION OVER feature.)

 

INLINE QUERY VERSION:

    SELECT clm_cd, prod_ser_no, bld_date, vin,   /*POST EDITED TO REMOVE TABLE ALIAS Q. from clm_cd */
            in_srvc_date, in_srvc_trk_mlg,
            in_service_year,
            prod_mdl_cd, voc_cd,
            prod_make_cd, fllc_internal_model,
            prod_fam_cd, chass_mdl_cd, flt_cd,
            flt_name, fail_date, trk_mlg_amt,
            eng_repl_mileage,
            eng_repl_date,
            max(eng_serial_number) OVER PARTITION BY (vin) as eng_serial_number,
            max(eng_model) OVER PARTITION BY (vin) as eng_model
     FROM (SELECT oc.clm_cd, p.prod_ser_no, p.bld_date, p.vin,
                                 p.in_srvc_date, p.in_srvc_trk_mlg,
                                year(p.in_srvc_date) as in_service_year,
                                case when p.prod_type_cd = 'ENGINE'
                                        then p.prod_ser_no else '' end as eng_serial_number,
                               case when p.prod_type_cd = 'ENGINE'
                                       then p.prod_mdl_cd else '' end as eng_model,
                               p.prod_mdl_cd, p.voc_cd,
                               p.prod_make_cd, p.prod_mdl_cd as fllc_internal_model,
                               p.prod_fam_cd, p.chass_mdl_cd, oc.flt_cd,
                               oc.flt_name, oc.fail_date, oc.trk_mlg_amt,
                               case when cfa.new_maj_comp_ser is not null
                                        then oc.trk_mlg_amt else 0 end as eng_repl_mileage,
                              case when cfa.new_maj_comp_ser is not null
                                       then oc.fail_date else '12-31-2999' end as eng_repl_date
             FROM wty_ddc.claims_fact_ddc_v oc
             INNER JOIN wty_ddc.product_dim_v p
             ON oc.prod_id = p.prod_id
             INNER JOIN wty_ddc.claims_fact_attr_ddc_v cfa
             ON cfa.clm_id = oc.clm_id
             WHERE trk_mlg_amt is not null and trk_mlg_amt > 0
                           and prod_type_cd in ('ENGINE','CHASSIS')
             ORDER BY vin, fail_date desc) 

 

ERROR: CLI describe error: [IBM][CLI Driver][DB2/AIX64] SQL0104N  An unexpected token "q.clm_cd, prod_ser_no,
       bld_date, vin, in_srvc_date, in" was found following "SELECT ".  Expected tokens may include: 
       "<space>".  SQLSTATE=42601

 

(Same interpretation here - I think the query would work if the outer select statement was just "select * from....", but that's useless.)

 

I have tried the same thing leaving out the two column specs using PARTITION BY, in case that was ultimately the source of the syntax problem.  However, this error code ultimately means the same thing as the earlier one:

 

ERROR: CLI describe error: [IBM][CLI Driver][DB2/AIX64] SQL0206N  "Q.CLM_CD" is not valid in the context
       where it is used.  SQLSTATE=42703

 

 

 

>>>  I think I could get the work done with several PROC SQL steps creating local temporary tables, but that will make this run much, much slower.

 

TIA!!

Steve

1 ACCEPTED SOLUTION

Accepted Solutions
fdsaaaa
Obsidian | Level 7

Right. I can only suggest you do what I would in this situation . 

 

You have said select * from works, So change that to select 1 column (with no min/max or any other derivations) and see if that works . Gradually add 1 column at a time to see what is the first change you make that causes the error to occur

 

then google 

 

good luck

View solution in original post

7 REPLIES 7
fdsaaaa
Obsidian | Level 7

To me this SQL looks invalid . 

 

You are asking for 

 

q.clm_cd,

 

 

but you have not defined q anywhere

saraimi
Fluorite | Level 6

Right - thanks.  I left out some of my debugging steps.  As a later debugging attempt, I threw an alias of "q" on the inline query and the select column specifications.  When I posted, I stripped off the alias on the virtual table definition, but forgot to remove it from the columns  

fdsaaaa
Obsidian | Level 7

Right. I can only suggest you do what I would in this situation . 

 

You have said select * from works, So change that to select 1 column (with no min/max or any other derivations) and see if that works . Gradually add 1 column at a time to see what is the first change you make that causes the error to occur

 

then google 

 

good luck

saraimi
Fluorite | Level 6

Thanks for illuminating my blind spot!  This works fine until I include one of the columns involving PARTITION OVER.  I'll dig into the details of that syntax.

saraimi
Fluorite | Level 6

...and the syntax for partition is this:

 

select max(whatever var) OVER (PARTITION BY vin),

....

Tom
Super User Tom
Super User

@saraimi wrote:

Thanks for illuminating my blind spot!  This works fine until I include one of the columns involving PARTITION OVER.  I'll dig into the details of that syntax.


What type of variable is eng_serial_number ?  Perhaps it is a BIGINT or other data type that SAS does not support.  If so cast it as FLOAT or VARCHAR(). 

 

Note that SAS only has two data types, floating point numbers and fixed length character strings.

saraimi
Fluorite | Level 6

Thanks, Tom - that is important to keep in mind.  In this case, it's character, and my problem was with the syntax of the OVER and PARTITION BY:

 

bad

   MAX(eng_serial_number) OVER PARTITION BY (vin);

 

good

   MAX(eng_serial_number) OVER (PARTITION BY vin);

 

 

 

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to connect to databases in SAS Viya

Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 7 replies
  • 4872 views
  • 4 likes
  • 3 in conversation