Birt report design in eclipse with subreport filter - eclipse

My query has too many subqueries and each query has repeated parameters. How to design the report in eclipse. This is my query
SELECT
C.COMP_CODE,C.MATCODE,C.ATTRIB1,C.ATTRIB2,C.MAT_NAME,C.SUP_PROD_CODE,
C.SUP_CODE,C.BRAND_CODE,C.CAT_CODE,SGRPCODE,SUB_SGRPCODE,C.UNIT_CODE,
NVL(SUM(D.SALES_QTY),0)SALES_QTY,
NVL(SUM(D.SALES_VAL),0) SALES_VAL,
MAX(COST_PRICE) GRN_COST_PRICE,GRN_DATE,'sales qty' a, 'sales val' b,'stock' c,'stock val' d
FROM
(
SELECT A.COMP_CODE,A.MATCODE,B.UNIT_CODE,A.ATTRIB1,A.ATTRIB2,MAT_NAME,SUP_PROD_CODE,
SUP_CODE,BRAND_CODE,CAT_CODE,SGRPCODE,SUB_SGRPCODE,COST_PRICE,GRN_DATE FROM
(
SELECT A.COMP_CODE,A.MATCODE,A.ATTRIB1,A.ATTRIB2,MAT_NAME,SUP_PROD_CODE,
SUP_CODE,BRAND_CODE,CAT_CODE,SGRPCODE,SUB_SGRPCODE,B.COST_PRICE,B.GRN_DATE FROM
(
SELECT A.COMP_CODE,A.MATCODE,A.ATTRIB1,A.ATTRIB2,B.MAT_NAME,B.SUP_PROD_CODE,
B.SUP_CODE,B.BRAND_CODE,B.CAT_CODE,B.SGRPCODE,B.SUB_SGRPCODE FROM
MAT_LIST A,
MATERIAL_MASTER B
WHERE A.COMP_CODE=B.COMP_CODE
AND A.MATCODE=B.MATCODE
--AND A.MATCODE='168847'
)A,
(SELECT A.COMP_CODE,A.MAIN_CODE,A.MATCODE,NVL(A.ATTRIB_CODE1,0) ATTRIB1,NVL(A.ATTRIB_CODE2,0) ATTRIB2,
A.MAT_TYPE,MAX(A.MAT_COST) COST_PRICE,GRN_DATE
FROM INV_GRN_DTL_V A
WHERE a.grn_date=(select max(b.grn_date) from inv_grn_dtl_v b
where b.comp_code=a.comp_code and
b.main_code=a.main_code and
b.matcode=a.matcode and
nvl(b.grn_status,'P')='A' and
nvl(b.auth_status,'P')='A' and
b.supcode<>'GDS1' and
b.grn_date<=:TO_DT)
AND NVL(A.GRN_STATUS,'P')='A'
AND NVL(A.AUTH_STATUS,'P')='A'
GROUP BY A.COMP_CODE,A.MAIN_CODE,A.MATCODE,A.ATTRIB_CODE1,A.ATTRIB_CODE2,A.MAT_TYPE,GRN_DATE
) B
WHERE A.COMP_CODE=B.COMP_CODE(+)
AND A.MATCODE=B.MATCODE(+)
AND A.ATTRIB1=B.ATTRIB1(+)
AND A.ATTRIB2=B.ATTRIB2(+)
AND A.COMP_CODE=:P_COMP_CODE)
A,(
SELECT COMP_CODE,MAIN_CODE,UNIT_CODE
FROM UNIT_MST WHERE COMP_CODE=56
AND UNIT_CODE IN (SELECT DISTINCT UNIT_CODE FROM STK_SALES_VU
WHERE ORD_DATE BETWEEN :FR_DT AND :TO_DT
AND COMP_CODE=:P_COMP_CODE)
--UNION ALL
--SELECT DISTINCT COMP_CODE,MAIN_CODE,'STOCK' FROM UNIT_MST WHERE COMP_CODE=:P_COMP_CODE
) B
WHERE A.COMP_CODE=B.COMP_CODE
AND A.COMP_CODE=:P_COMP_CODE
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND CAT_CODE BETWEEN DECODE(:FR_CAT,'ALL',CAT_CODE,:FR_CAT)
AND DECODE(:TO_CAT,'ALL',CAT_CODE,:TO_CAT)
AND SUP_CODE=DECODE(:P_SUP_CODE,'ALL',SUP_CODE,:P_SUP_CODE))
C,(
SELECT COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0) ATTRIB_CODE1,NVL(ATTRIB_CODE2,0) ATTRIB_CODE2,
NVL(SUM(SALES_QTY),0) SALES_QTY, SUM(COST_VAL) SALES_VAL
FROM
(
SELECT COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,NVL(B.ATTRIB_CODE1,0) ATTRIB_CODE1,NVL(B.ATTRIB_CODE2,0) ATTRIB_CODE2,
NVL(SUM(B.SALE_QTY),0) SALES_QTY, SUM(B.VAL) COST_VAL
FROM STK_SALES_VU_ATT B
WHERE ORD_DATE BETWEEN :FR_DT AND :TO_DT
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND COMP_CODE=:P_COMP_CODE
GROUP BY COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,NVL(B.ATTRIB_CODE1,0),NVL(B.ATTRIB_CODE2,0)
UNION ALL
SELECT COMP_CODE,MAIN_CODE,'STOCK' UNIT_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0),SUM(INC_QTY)-SUM(DEC_QTY) OB_QTY, 0 SALES_VAL
FROM INV_TRN_DAY_SUM_VU_ATT
WHERE TRN_DATE BETWEEN :FR_DT AND :TO_DT
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND COMP_CODE=:P_COMP_CODE
GROUP BY COMP_CODE,MAIN_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0)
UNION ALL
SELECT COMP_CODE,MAIN_CODE,'STOCK' UNIT_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0),SUM(QTY)QTY, 0 SALES_VAL
FROM MATERIAL_DETAIL
WHERE SERIAL=:P_FNYR
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND COMP_CODE=:P_COMP_CODE
GROUP BY COMP_CODE,MAIN_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0)
)
--WHERE MATCODE='168847'
GROUP BY COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,ATTRIB_CODE1,ATTRIB_CODE2
) D
WHERE C.COMP_CODE = D.COMP_CODE (+)
AND C.UNIT_CODE = D.UNIT_CODE(+)
AND C.MATCODE = D.MATCODE(+)
--AND C.MATCODE='168847'
AND C.ATTRIB1 = D.ATTRIB_CODE1(+)
AND C.ATTRIB2 = D.ATTRIB_CODE2(+)
AND C.COMP_CODE=:P_COMP_CODE
AND C.UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',C.UNIT_CODE,:P_UNIT_CODE)
GROUP BY
C.COMP_CODE,C.MATCODE,C.ATTRIB1,C.ATTRIB2,C.MAT_NAME,C.SUP_PROD_CODE,
C.SUP_CODE,C.BRAND_CODE,C.CAT_CODE,SGRPCODE,SUB_SGRPCODE,C.UNIT_CODE,GRN_DATE
order by c.unit_code
The parameters are (:FR_DT,:TO_DT, : p_COMP_CODE, :FR_CAT, :TO_CAT, : p_SUP_CODE) which need to be replaced with '?' while writing the query in dataset. But i don't know how to replace same parameter which is occurring at multiple places with the query parameters. and How to handle DECODE and between parametes.

One option is to use a WITH clause to assign your parameters to a dummy table.
WITH tmp_parms AS (
SELECT ? as fr_dt, ? as to_dt, ? as p_comp_code,
? as fr_cat, ? as to_cat, ? as p_sub_code
FROM dual
)
SELECT C.COMP_CODE,C.MATCODE, ... etc
FROM tmp_parms tp,
(
SELECT A.COMP_CODE,A.MATCODE, ... etc
Or if you'd prefer yet another inline view:
SELECT C.COMP_CODE,C.MATCODE, ... etc
FROM (
SELECT ? as fr_dt, ? as to_dt, ? as p_comp_code,
? as fr_cat, ? as to_cat, ? as p_sub_code
FROM dual
) tp,
(
SELECT A.COMP_CODE,A.MATCODE, ... etc
And then replace all the existing bind variables with references to the equivalent column from the temporary parms table, i.e. change this:
b.grn_date<=:TO_DT)
to this:
b.grn_date<=tp.to_dt)

Related

How to add a label based on dense rank value [duplicate]

This question already exists:
Cannot when add ORDER BY in a CTE
Closed 9 months ago.
Is there any way I can reference the inner dense rank results and give them appropriate labels like I am trying to do? It seems like in T-SQL I just can NOT do an "Order by" in an inner query, it is producing an error like:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
But then how do I attach appropriate labels to the dense rank results in the code below?
WITH basequery AS (
SELECT c.baseentityid,
c.team,
c.providerid,
-- rank() OVER (PARTITION BY c.baseentityid ORDER BY c.version DESC) AS rn,
t.vaccinedate,
t.vaccine,
t.vaccinesource,
t.num
FROM vr.child_registration c
CROSS APPLY ( VALUES (c.bcgsource,c.bcgdate,'bcg',1), (c.opv0source,c.opv0date,'opv0',2), (c.penta1source,c.penta1date,'penta1',3), (c.pcv1source,c.pcv1date,'pcv1',4), (c.rota1source,c.rota1date,'rota1',5), (c.opv1source,c.opv1date,'opv1',6), (c.penta2source,c.penta2date,'penta2',7), (c.pcv2source,c.pcv2date,'pcv2',8), (c.rota2source,c.rota2date,'rota2',9), (c.opv2source,c.opv2date,'opv2',10), (c.penta3source,c.penta3date,'penta3',11), (c.ipvsource,c.ipvdate,'ipv',12), (c.pcv3source,c.pcv3date,'pcv3',13), (c.opv3source,c.opv3date,'opv3',14), (c.measles1source,c.measles1date,'measles1',15), (c.tcvsource,c.tcvdate,'tcv',16), (c.ipv2source,c.ipv2date,'ipv2',17), (c.measles2source,c.measles2date,'measles2',18)) t(vaccinesource, vaccinedate, vaccine, num)
WHERE t.vaccinedate IS NOT NULL AND t.vaccinedate <> ''
)
SELECT aa.baseentityid,
aa.team,
aa.vaccinedate,
aa.vaccine,
aa.vaccinesource,
aa.num,
aa.providerid,
aa.visitrank,
CASE
WHEN aa.visitrank = 0 THEN 'external vaccination'
WHEN aa.visitrank = 1 THEN 'Enrollment'
ELSE 'Visitation'
END AS visittype,
CASE
WHEN aa.providerid LIKE '%vacc%' THEN 'Vacc'
ELSE 'Non-Vacc'
END AS providertype
FROM ( SELECT a.baseentityid,
a.team,
a.vaccinedate,
a.vaccine,
a.vaccinesource,
a.num,
a.providerid,
CASE
WHEN a.vaccinesource = 'vaccinatoradministered' THEN dense_rank() OVER (PARTITION BY a.baseentityid, (
CASE
WHEN a.vaccinesource = 'vaccinatoradministered' THEN 1
ELSE 0
END) ORDER BY (CONVERT(VARCHAR(10),a.vaccinedate,111)) )
ELSE 0
END AS visitrank
FROM basequery a
WHERE a.rn = 1
GROUP BY a.baseentityid, a.team, a.vaccinedate, a.vaccine, a.vaccinesource, a.num, a.providerid
ORDER BY a.baseentityid, a.num) aa;

Query returning different number of rows, results in crosstab error

I get this error with my query, but I can't figure out what is wrong with it:
Query-specified return tuple has 135 columns but crosstab returns 295.
And here's my query: (The part highlighted in bold returns same number of rows when run separately in pgAdmin.)
SELECT X.*, pi.productcode, pi.productitemdesc, pi.retailsalesprice, cat.productcategorydesc FROM (
SELECT * FROM crosstab (
'SELECT a.productitem AS productitemid, l.locationcode, (CASE WHEN SUM(a.netamount) IS NOT NULL THEN SUM(a.netamount) ELSE 0 END) || ''#'' || (CASE WHEN SUM(a.quantity) IS NOT NULL THEN SUM(a.quantity) ELSE 0 END) AS sales_qty FROM invoiceitem a INNER JOIN invoiceinfo b ON a.invoice = b.invoiceid INNER JOIN locationinfo l ON b.location = l.locationid WHERE b.status !=2 AND l.locationtype = 1 AND l.status = 1 AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')>=''2018-03-01'' AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')<=''2018-03-03'' GROUP BY a.productitem, l.locationcode ORDER BY a.productitem',
'SELECT l.locationcode FROM locationinfo l INNER JOIN invoiceinfo b ON b.location = l.locationid
WHERE b.status !=2 AND l.locationtype = 1 AND l.status = 1 AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')>=''2018-03-01'' AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')<=''2018-03-03'' GROUP BY l.locationcode order by l.locationcode')
AS (productitemid int, "0007" text,"BE101" text,"BE1013" text,"BE1014" text,"BE102" text,"BE103" text,"BE1034" text,"BE104" text,"BE1040" text,"BE1043" text,"BE1044" text,"BE1045" text,"BE1046" text,"BE105" text,"BE106" text,"BE107" text,"BE108" text,"BE109" text,"BE110" text,"BE111" text,"BE112" text,"BE123" text,"BE1265" text,"BE1266" text,"BE1271" text,"BE1272" text,"BE1273" text,"BE1274" text,"BE1279" text,"BE1280" text,"BE1281" text,"BE1282" text,"BE1351" text,"BE1400" text,"BE1401" text,"BE1404" text,"BE141" text,"BE142" text,"BE193" text,"BE194" text,"BE2125" text,"BE2126" text,"BE2127" text,"BE2128" text,"BE3001" text,"BE3002" text,"BE3005" text,"BE3006" text,"BE3009" text,"BE3010" text,"BE3031" text,"BE3032" text,"BE3121" text,"BE3122" text,"BE3123" text,"BE3124" text,"BE3127" text,"BE3128" text,"BE3131" text,"BE3132" text,"BE3203" text,"BE3204" text,"BE325" text,"BE3253" text,"BE3254" text,"BE326" text,"BE332" text,"BE3503" text,"BE3504" text,"BE355" text,"BE356" text,"BE365" text,"BE366" text,"BE381" text,"BE382" text,"BE383" text,"BE384" text,"BE400" text,"BE401" text,"BE402" text,"BE403" text,"BE405" text,"BE406" text,"BE408" text,"BE409" text,"BE411" text,"BE412" text,"BE4311" text,"BE4316" text,"BE4401" text,"BE4402" text,"BE4521" text,"BE4522" text,"BE4551" text,"BE4552" text,"BE470" text,"BE473" text,"BE475" text,"BE481" text,"BE482" text,"BE601" text,"BE604" text,"BE609" text,"BE610" text,"BE7040" text,"BE7043" text,"BE7045" text,"BE7046" text,"BE7048" text,"BE7049" text,"BE708" text,"BE7111" text,"BE7112" text,"BE7127" text,"BE7128" text,"BE7217" text,"BE7218" text,"BE7307" text,"BE7308" text,"BE7351" text,"BE7352" text,"BE801" text,"BE802" text,"BE803" text,"BE804" text,"BE831" text,"BE832" text,"BE860" text,"BE861" text,"BE862" text,"BE863" text,"BE865" text,"BE981" text,"BE982" text
)) X
LEFT JOIN productitem pi ON X.productitemid = pi.productitemid
LEFT JOIN productcategory cat ON pi.productcategory = cat.productcategoryid
The bold part of
productitemid int, "0007" text,"BE101" text,"BE1013" text,"BE1014" text,"BE102" text,"BE103" text,"BE1034" text,"BE104" text,"BE1040" text,"BE1043" text,"BE1044" text,"BE1045" text,"BE1046" text,"BE105" text,"BE106" text,"BE107" text,"BE108" text,"BE109" text,"BE110" text,"BE111" text,"BE112" text,"BE123" text,"BE1265" text,"BE1266" text,"BE1271" text,"BE1272" text,"BE1273" text,"BE1274" text,"BE1279" text,"BE1280" text,"BE1281" text,"BE1282" text,"BE1351" text,"BE1400" text,"BE1401" text,"BE1404" text,"BE141" text,"BE142" text,"BE193" text,"BE194" text,"BE2125" text,"BE2126" text,"BE2127" text,"BE2128" text,"BE3001" text,"BE3002" text,"BE3005" text,"BE3006" text,"BE3009" text,"BE3010" text,"BE3031" text,"BE3032" text,"BE3121" text,"BE3122" text,"BE3123" text,"BE3124" text,"BE3127" text,"BE3128" text,"BE3131" text,"BE3132" text,"BE3203" text,"BE3204" text,"BE325" text,"BE3253" text,"BE3254" text,"BE326" text,"BE332" text,"BE3503" text,"BE3504" text,"BE355" text,"BE356" text,"BE365" text,"BE366" text,"BE381" text,"BE382" text,"BE383" text,"BE384" text,"BE400" text,"BE401" text,"BE402" text,"BE403" text,"BE405" text,"BE406" text,"BE408" text,"BE409" text,"BE411" text,"BE412" text,"BE4311" text,"BE4316" text,"BE4401" text,"BE4402" text,"BE4521" text,"BE4522" text,"BE4551" text,"BE4552" text,"BE470" text,"BE473" text,"BE475" text,"BE481" text,"BE482" text,"BE601" text,"BE604" text,"BE609" text,"BE610" text,"BE7040" text,"BE7043" text,"BE7045" text,"BE7046" text,"BE7048" text,"BE7049" text,"BE708" text,"BE7111" text,"BE7112" text,"BE7127" text,"BE7128" text,"BE7217" text,"BE7218" text,"BE7307" text,"BE7308" text,"BE7351" text,"BE7352" text,"BE801" text,"BE802" text,"BE803" text,"BE804" text,"BE831" text,"BE832" text,"BE860" text,"BE861" text,"BE862" text,"BE863" text,"BE865" text,"BE981" text,"BE982" text
AND
SELECT l.locationcode FROM locationinfo l INNER JOIN invoiceinfo b ON b.location = l.locationid
WHERE b.status !=2 AND l.locationtype = 1 AND l.status = 1 AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')>=''2018-03-01'' AND TO_CHAR (b.invoicedate, ''YYYY-MM-DD'')<=''2018-03-03'' GROUP BY l.locationcode order by l.locationcode
When run seperately, I get 295 results which is correct. However putting it together in the whole query gets the error.
The manual:
The remaining output columns must have the type of the last column of the source_sql query's result, and there must be exactly as many of them as there are rows in the category_sql query's result.
crosstab(text, text) with a dynamic (!) SELECT query as 2nd parameter is very error prone, since the output column list is static. You should also generate the output column list dynamically. Example:
Dynamic alternative to pivot with CASE and GROUP BY
That aside, the different number of rows returned from the same query, may very well be due to a different timezone setting in the two different sessions.
You have the expression TO_CHAR(b.invoicedate, 'YYYY-MM-DD') in your predicates. If b.invoicedate is type timestamptz the result depends on the timezone setting. Consider:
SET timezone = '+10';
SELECT TO_CHAR(timestamptz '2018-04-07 23:30+0', 'YYYY-MM-DD');
to_char
----------
2018-04-08
SET timezone = '-10';
SELECT TO_CHAR(timestamptz '2018-04-07 23:30+0', 'YYYY-MM-DD');
to_char
----------
2018-04-07
Solution
To remove the dependency on the timezone setting, use absolute values.
to_char() is expensive complication in this place to begin with. Drop that and adjust the predicate.
Provide timestamptz values to match your column. This also allows indexes to be used (if applicable).
Return Table Type from A function in PostgreSQL
Use time zone names (not offsets or abbreviations) to avoid more misunderstandings.
Ignoring timezones altogether in Rails and PostgreSQL
Use dollar-quoting to clean up the quote mess.
Insert text with single quotes in PostgreSQL
I suggest this as 2nd parameter:
$$
SELECT l.locationcode
FROM locationinfo l
JOIN invoiceinfo b ON b.location = l.locationid
WHERE b.status <> 2 AND l.locationtype = 1 AND l.status = 1
AND b.invoicedate >= timestamptz '2018-03-01 Europe/Vienna'
AND b.invoicedate < timestamptz '2018-03-04 Europe/Vienna'
GROUP BY 1
ORDER BY 1
$$
Replace Europe/Vienna in my example with the time zone name defining your dates.
Note 2018-03-04 to include all of 2018-03-03 like you intended.

Run function with select statement

I have a tabe valued function called "GetLogInfosMsg" which I want to run provided with some Parameters from a specific table. The code below does not work; I get the message "Only one expression can be specified in the select list when the sub-query is not introduced with EXISTS.". Can somebody help me? Thanks.
SELECT
#pErrMsgID = [MsgID],
#pParams = [Params]
FROM
[dbo].[GetLogInfoMsg]((SELECT
[FIELD1],
[FIELD2],
[FIELD3]
FROM [dbo].[TABLE1]
WHERE [TABLE1].[UUID] = #pUUID));
try this
you have to pass parameter in separate not in table format
SELECT #pErrMsgID = [MsgID] ,
#pParams = [Params]
FROM [dbo].[GetLogInfoMsg](( SELECT [FIELD1]
FROM [dbo].[TABLE1]
WHERE [TABLE1].[UUID] = #pUUID
), ( SELECT [FIELD2]
FROM [dbo].[TABLE1]
WHERE [TABLE1].[UUID] = #pUUID
), ( SELECT [FIELD3]
FROM [dbo].[TABLE1]
WHERE [TABLE1].[UUID] = #pUUID
)) ;
If you are using mssql 2005+ consider using this:
SELECT
#pErrMsgID = t2.[MsgID],
#pParams = t2.[Params]
FROM [dbo].[TABLE1] t1
CROSS APPLY (SELECT [MsgID], [Params]
FROM [dbo].[GetLogInfoMsg] (t1.FIELD1, t1.FIELD2, t1.FIELD3) t2
WHERE t1.[UUID] = #pUUID

Is there a JDFTVAL equivalent for SQL?

For Iseries/IBMi DB2.
I am joining multiple files/tables together.
I have written the code in both DDS and SQL.
The DDS Logical File is working exactly as expected, but I can not use it for embedded sql in rpgle as it then defaults to the SQE engine resulting in horrendous performance.
The SQL view, on the other hand had NULLs until I used IFNULL( MBRDESCR, ''). But now MBRDECSR is a VARCHAR. Which is unacceptable.
So how do I create a SQL join without NULLs and VARCHARs?
Requested Sample Code:
DDS:
JDFTVAL
R TRANSR JFILE(TRANSPF MBRPF)
J JOIN(1 2)
JFLD(MBRID MBRID)
*
TRANSID JREF(1)
MBRID JREF(1)
MBRNAME JREF(2)
MBRSURNME JREF(2)
*
K TRANSID
K MBRID
SQL:
CREATE VIEW TRANSV01 AS (
SELECT TRANSID ,
MBRID ,
CAST(IFNULL(MBRNAME , '') as Char(20)) ,
CAST(IFNULL(MBRSURNME, '') as Char(25))
FROM TRANSPF
--Member Name
LEFT OUTER JOIN MBRPF on MBRID = MBRID
) RCDFMT TRANSR;
Please note the following:
Example above is simplified
Not every MBRID in the TRANSPF has a corresponding entry in the MBRPF (ie. no referential constraint). Thus when MBRPF is joined to the TRANSPF, there will be NULL values in MBRNAME, MBRSURNME. Unless JDFTVAL or IFNULL() is used.
I prefer not to have a VARCHAR, because of performance and extname() in rpgle.
I prefer not to have NULL values, I do not want the pgm to have to handle them.
Assuming it's the 'Allows the null value' that you find undesirable, use a UNION. The first SELECT chooses all the rows that match, which will set the NOT NULL property for you. The second SELECT chooses all the rows that don't have a match - you provide filler fields for those.
CREATE VIEW TRANSV01 AS (
SELECT TRANSID ,
MBRID ,
MBRNAME ,
MBRSURNME
FROM TRANSPF
--Member Name
JOIN MBRPF on MBRID = MBRID
UNION
SELECT TRANSID ,
MBRID ,
CAST('') as Char(20)) ,
CAST('') as Char(25))
FROM TRANSPF
--Member Name
EXCEPTION JOIN MBRPF on MBRID = MBRID
) RCDFMT TRANSR;

TSQL CTE Error: Incorrect syntax near ')'

I am developing a TSQL stored proc using SSMS 2008 and am receiving the above error while generating a CTE. I want to add logic to this SP to return every day, not just the days with data. How do I do this? Here is my SP so far:
ALTER Proc [dbo].[rpt_rd_CensusWithChart]
#program uniqueidentifier = NULL,
#office uniqueidentifier = NULL
AS
DECLARE #a_date datetime
SET #a_date = case when MONTH(GETDATE()) >= 7 THEN '7/1/' + CAST(YEAR(GETDATE()) AS VARCHAR(30))
ELSE '7/1/' + CAST(YEAR(GETDATE())-1 AS VARCHAR(30)) END
if exists (
select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#ENROLLEES')
) DROP TABLE #ENROLLEES;
if exists (
select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#DISCHARGES')
) DROP TABLE #DISCHARGES;
declare #sum_enrollment int
set #sum_enrollment =
(select sum(1)
from enrollment_view A
join enrollment_info_expanded_view C on A.enrollment_id = C.enroll_el_id
where
(#office is NULL OR A.group_profile_id = #office)
AND (#program is NULL OR A.program_info_id = #program)
and (C.pe_end_date IS NULL OR C.pe_end_date > #a_date)
AND C.pe_start_date IS NOT NULL and C.pe_start_date < #a_date)
select
A.program_info_id as [Program code],
A.[program_name],
A.profile_name as Facility,
A.group_profile_id as Facility_code,
A.people_id,
1 as enrollment_id,
C.pe_start_date,
C.pe_end_date,
LEFT(datename(month,(C.pe_start_date)),3) as a_month,
day(C.pe_start_date) as a_day,
#sum_enrollment as sum_enrollment
into #ENROLLEES
from enrollment_view A
join enrollment_info_expanded_view C on A.enrollment_id = C.enroll_el_id
where
(#office is NULL OR A.group_profile_id = #office)
AND (#program is NULL OR A.program_info_id = #program)
and (C.pe_end_date IS NULL OR C.pe_end_date > #a_date)
AND C.pe_start_date IS NOT NULL and C.pe_start_date >= #a_date
;WITH #ENROLLEES AS (
SELECT '7/1/11' AS dt
UNION ALL
SELECT DATEADD(d, 1, pe_start_date) as dt
FROM #ENROLLEES s
WHERE DATEADD(d, 1, pe_start_date) <= '12/1/11')
The most obvious issue (and probably the one that causes the error message too) is the absence of the actual statement to which the last CTE is supposed to pertain. I presume it should be a SELECT statement, one that would combine the result set of the CTE with the data from the #ENROLLEES table.
And that's where another issue emerges.
You see, apart from the fact that a name that starts with a single # is hardly advisable for anything that is not a local temporary table (a CTE is not a table indeed), you've also chosen for your CTE a particular name that already belongs to an existing table (more precisely, to the already mentioned #ENROLLEES temporary table), and the one you are going to pull data from too. You should definitely not use an existing table's name for a CTE, or you will not be able to join it with the CTE due to the name conflict.
It also appears that, based on its code, the last CTE represents an unfinished implementation of the logic you say you want to add to the SP. I can suggest some idea, but before I go on I'd like you to realise that there are actually two different requests in your post. One is about finding the cause of the error message, the other is about code for a new logic. Generally you are probably better off separating such requests into distinct questions, and so you might be in this case as well.
Anyway, here's my suggestion:
build a complete list of dates you want to be accounted for in the result set (that's what the CTE will be used for);
left-join that list with the #ENROLLEES table to pick data for the existing dates and some defaults or NULLs for the non-existing ones.
It might be implemented like this:
… /* all your code up until the last WITH */
;
WITH cte AS (
SELECT CAST('7/1/11' AS date) AS dt
UNION ALL
SELECT DATEADD(d, 1, dt) as dt
FROM cte
WHERE dt < '12/1/11'
)
SELECT
cte.dt,
tmp.[Program code],
tmp.[program_name],
… /* other columns as necessary; you might also consider
enveloping some or all of the "tmp" columns in ISNULLs,
like in
ISNULL(tmp.[Program code], '(none)') AS [Program code]
to provide default values for absent data */
FROM cte
LEFT JOIN #ENROLLEES tmp ON cte.dt = tmp.pe_start_date
;