SQL Server. dynamic query error while using aggregate function - sql

I am little bit new to SQL. I am trying to run below shown dynamic query
SET #SQL ='
select Distinct count(*) TotalCount,
sum(case when ap.FormStatus = ''open'' then 1 else 0 end) AS Totalopenstatus,
sum(case when ap.FormStatus = ''Pending'' then 1 else 0 end) AS TotalPendingstatus,
sum(case when ap.FormStatus = ''Awaiting L1 Review'' then 1 else 0 end) AS TotalAssociates,
sum(case when ap.FormStatus = ''Awaiting L2 Review'' then 1 else 0 end) AS TotalL1reviews,
sum(case when ap.FormStatus = ''Awaiting Delivery Head'' then 1 else 0 end) AS TotalL2reviews
from [dbo].[Appraisals] ap
LEFT join [dbo].[FinalReviewClosures] fi ON ap.FinalReviewClosure_Id = fi.id
join [dbo].[employees] emp ON fi.Employee_Id = emp.id
where fi.FinancialYear ='+#FinancialYear +' AND ap.Quarter = '+#Quarter+' '
but I get this error:
Msg 245, Level 16, State 1, Procedure sp_GetReviewStatus, Line 51 [Batch Start Line 11]
Conversion failed when converting the nvarchar value
Code:
select Distinct count(*) TotalCount,
sum(case when ap.FormStatus = 'open' then 1 else 0 end) AS Totalopenstatus,
sum(case when ap.FormStatus = 'Pending' then 1 else 0 end) AS TotalPendingstatus,
sum(case when ap.FormStatus = 'Awaiting L1 Review' then 1 else 0 end) AS TotalAssociates,
sum(case when ap.FormStatus = 'Awaiting L2 Review' then 1 else 0 end) AS TotalL1reviews,
sum(case when ap.FormStatus = 'Awaiting Delivery Head' then 1 else 0 end) AS TotalL2reviews
from [dbo].[Appraisals] ap
LEFT join [dbo].[FinalReviewClosures] fi ON ap.FinalReviewClosure_Id = fi.id
join [dbo].[employees] emp ON fi.Employee_Id = emp.id
where fi.FinancialYear =2020-2021 AND ap.Quarter = Q3 AND emp.office = ' to data type int.
Please help me fix this problem.

The reason what you have is failing is as has been mentioned. You are injecting values instead of parametrising and these values are creating invalid syntax in your "dynamic" query. (Read on to see why I say "dynamic".)
fi.FinancialYear ='+#FinancialYear +' becomes fi.FinancialYear =2020-2021, which is effectively fi.FinancialYear = -1 (what year is -1?). This will cause an error if fi.FinancialYear isn't able to be converted implicitly to an int.
ap.Quarter = '+#Quarter becomes ap.Quarter = Q3 and unless you have a column called Q3 then you're going to get an invalid column error.
If you are using dynamic SQL then never inject unsanitised values; quote your object names using QUOTENAME and parametrise your parameters (which you can do with sys.sp_executesql).
What you have, however, has no need to be a "dynamic" query; there is nothing dynamic about it. Just use a non-dynamic parametrised query and the query will work fine:
SELECT --DISTINCT --Not needed, as the query will only return 1 row.
--Even if you did have a GROUP BY the DISTINCT isn't needed,
--as the GROUP BY will already put the data in DISTINCT sets.
COUNT(*) AS TotalCount,
SUM(CASE WHEN ap.FormStatus = 'open' THEN 1 ELSE 0 END) AS Totalopenstatus,
SUM(CASE WHEN ap.FormStatus = 'Pending' THEN 1 ELSE 0 END) AS TotalPendingstatus,
SUM(CASE WHEN ap.FormStatus = 'Awaiting L1 Review' THEN 1 ELSE 0 END) AS TotalAssociates,
SUM(CASE WHEN ap.FormStatus = 'Awaiting L2 Review' THEN 1 ELSE 0 END) AS TotalL1reviews,
SUM(CASE WHEN ap.FormStatus = 'Awaiting Delivery Head' THEN 1 ELSE 0 END) AS TotalL2reviews
FROM [dbo].[Appraisals] ap
LEFT JOIN [dbo].[FinalReviewClosures] fi ON ap.FinalReviewClosure_Id = fi.id
JOIN [dbo].[employees] emp ON fi.Employee_Id = emp.id
WHERE fi.FinancialYear = #FinancialYear --I assume fi.FinancialYear and #FinancialYear have the same data type?
AND ap.Quarter = #Quarter; --I assume ap.Quarter and #Quarter have the same data type?

Where clause should be
where fi.FinancialYear ='2020-2021' AND ap.Quarter = 'Q3' AND emp.office = ' to data type int.'
instead of
where fi.FinancialYear =2020-2021 AND ap.Quarter = Q3 AND emp.office = ' to data type int.
Please also let me know the data type of #financialYear and #Quarter

Related

Oracle stored procedure with function ORA-08103

I have a stored procedure that has a function call, and I get the below errors after about 10 mins of it running:
[Error] Execution (1: 1):
ORA-08103: object no longer exists
ORA-06512: at "CRYSTAL_REPORTS.FT_PAYCOM_ASOF", line 141
ORA-06512: at "CRYSTAL_REPORTS.PROC_DASHQS_PRODUCTION", line 26
ORA-06512: at line 2
However the function does exist and works as expected. Stripping down the query returns results, so I am concerned that complexity may be the cause. I appreciate any help, below is the procedure:
select
to_char(dt.dt,'YYYYMM') yearmonth,
ud.user_id,
CRYSTAL_REPORTS.FT_PAYCOM_ASOF(ud.user_eecode, dt.dt, 'DEPT') department,
CRYSTAL_REPORTS.FT_PAYCOM_ASOF(ud.user_eecode, dt.dt, 'PDEPT') par_department,
sum(case when clm.event_desc = 'NEW-OPEN' then 1 else 0 end) new_claim,
sum(case when clm.event_desc in ('INITIAL-CLOSE', 'RECLOSE', 'VOID') then 1 else 0 end) close_claim,
sum(case when clm.event_desc ='REOPEN' then 1 else 0 end) reopen_claim,
sum(case when clm.event_desc ='TRANSFER-IN' then 1 else 0 end) trans_in_claim,
sum(case when clm.event_desc ='TRANSFER-OUT' then 1 else 0 end) trans_out_claim,
sum(case when res.event_desc ='NEW-OPEN' then 1 else 0 end) new_res,
sum(case when res.event_desc in ('INITIAL-CLOSE','RECLOSE','VOID') then 1 else 0 end) close_res,
sum(case when res.event_desc ='REOPEN' then 1 else 0 end) reopen_res,
sum(case when res.event_desc ='TRANSFER-IN' then 1 else 0 end) trans_in_res,
sum(case when res.event_desc ='TRANSFER-OUT' then 1 else 0 end) trans_out_res,
sum(clm_wh.pending) pending_claims,
sum(res_wh.pending) pending_reserves
from
(select "DATE" dt from CRYSTAL_REPORTS.MV_CALENDAR_MONTHDATE) dt
cross join
crystal_reports.user_director ud
left join
CRYSTAL_REPORTS.MV_PROD_CLM_EVENT clm on clm.USER_ID = ud.USER_ID and to_char(clm.event_date,'YYYYMM') = to_char(dt.dt,'YYYYMM')
left join
CRYSTAL_REPORTS.MV_PROD_RES_EVENT res on res.USER_ID = ud.USER_ID and to_char(res.event_date,'YYYYMM')=to_char(dt.dt,'YYYYMM')
left join
crystal_reports.TBL_CLAIM_PROD_WH clm_wh on clm_wh.ADJUSTER=ud.user_id and clm_wh.type='MONTH' and to_char(dt.dt,'YYYYMM')= clm_wh.datadate
left join
crystal_reports.TBL_FEAT_PROD_WH res_wh on res_wh.ADJUSTER=ud.user_id and res_wh.type='MONTH' and to_char(dt.dt,'YYYYMM')= res_wh.datadate
where
to_char(dt.dt,'YYYYMMDD') = 20210901
and ud.user_id not like '%TEST%'
group by
to_char(dt.dt,'YYYYMM'), ud.user_id,
CRYSTAL_REPORTS.FT_PAYCOM_ASOF(ud.user_eecode, dt.dt, 'DEPT'),
CRYSTAL_REPORTS.FT_PAYCOM_ASOF(ud.user_eecode, dt.dt, 'PDEPT')
The function goes through several IF statements, and ends up using:
SELECT upper(case when uc_dept.detaildesc is null and orig_dept.detaildesc is null then upper(pext_dept.detaildesc) else upper(nvl(uc_dept.detaildesc,orig_dept.detaildesc)) end)
INTO xout_val
FROM crystal_reports.API_PAYCOM_USER_EXTENDED pext
left join crystal_reports.API_PAYCOM_USER_CHANGES uc on pext.EECODE = uc.EECODE and changedesc='PAF: Department Change' and (to_date(substr(changetime, 1,10), 'yyyy-mm-dd')) <= asof
left join crystal_reports.api_paycom_category pext_dept on pext_dept.detailcode=pext.DEPARTMENT_CODE
left join crystal_reports.api_paycom_category uc_dept on uc_dept.DETAILCODE=uc.new_value
left join (select eecode, orig_value,rn
from
(
select eecode,old_value orig_value, row_number() over (partition by eecode order by (to_date(substr(changetime, 1,10), 'yyyy-mm-dd')) asc) rn
from
crystal_reports.API_PAYCOM_USER_CHANGES orig_val
where changedesc='PAF: Department Change'
)
) orig_val on pext.eecode=orig_val.eecode and orig_val.rn=1
left join crystal_reports.api_paycom_category orig_dept on orig_dept.detailcode=orig_val.orig_value
where
acct=pext.eecode
order by (to_date(substr(changetime, 1,10), 'yyyy-mm-dd')) desc
FETCH NEXT 1 ROWS ONLY
It is very hard to remote diagnose such an error but in my experience the most likely cause of this error is another process/user that has removed the object since the operation has begun.
Alternatively there are also some Oracle bugs related to this error and you might want to check your alert log and eventually ask Oracle for help using MOS.

SQL Year over Year Performance with Criteria

I am trying to return year over year results based on date criteria. There is additional information I would like to include in the query i.e. first date of activity and first date of activity with spot name like '%6%'. The current query I have is multiplying the correct amounts by 6 and I can't figure out how to solve. When I remove the first "where" clause I get the correct amounts. Any help would be appreciated.
Select
V.IGB_License,
DBA,
V.Sci_Games_Name,
convert(date,v2.Activity_date) as First6thMachineDate,
convert(date,V3.Activity_date) as GoLiveDate,
sum(case when (v.Activity_date between '1/23/2019' and DATEADD(YEAR,-2,getdate()-1)) then v.Funds_in else 0 end) as FundsIn2019,
sum(case when (v.Activity_date between '1/23/2020' and DATEADD(YEAR,-1,getdate()-1)) then v.Funds_in else 0 end) as FundsIn2020,
sum(case when (v.Activity_date between '1/23/2021' and getdate()) then v.Funds_in else 0 end) as FundsIn2021,
sum(case when (v.Activity_date between '1/23/2019' and DATEADD(YEAR,-2,getdate()-1)) then v.Net_funds else 0 end) as NetFunds2019,
sum(case when (v.Activity_date between '1/23/2020' and DATEADD(YEAR,-1,getdate()-1)) then v.Net_funds else 0 end) as NetFunds2020,
sum(case when (v.Activity_date between '1/23/2021' and getdate()) then v.Net_funds else 0 end) as NetFunds2021
From VGT_activity V
Left Join Locations on v.IGB_License = Locations.IGB_License
left join VGT_activity V2 on v.IGB_License = v2.IGB_License
Left join VGT_activity V3 on v.IGB_License = v3.IGB_License
Where v2.Activity_date = (
Select Min(V1.Activity_date)
From VGT_activity V1
Where v1.IGB_License = V2.IGB_License
and Spot_name like '%6%'
)
and v3.Activity_date = (
Select Min(V1.Activity_date)
From VGT_activity V1
Where v1.IGB_License = V3.IGB_License
)
group by V.IGB_License, dba, V.Sci_Games_Name, v2.Activity_date, v3.Activity_date
order by 4

Dynamicaly Naming Columns - Using SQL server 2008

I have query that that references a dynamic calander table, it updates aged periods based on the current date. I am using this table in another query, it sum's sales value based on aged QTR's. These values will update as time passes and I can assign colmn names such as 'AGED1Q' but I would like to find a way to use the actual period name from the calander table. Any sugestions will be greatly appreciated.
Current query is below, I have added a few comment lines where I would like to make the changes. Thanks again
SELECT dbo.CUSTOMER_ORDER.CUSTOMER_ID AS CUST_ID,
SUM(CASE WHEN dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -4 THEN dbo.CUST_ORDER_LINE.TOTAL_AMT_ORDERED ELSE 0 END) AS '-4', --As MAX(dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTR) WHERE dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -4
SUM(CASE WHEN dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -3 THEN dbo.CUST_ORDER_LINE.TOTAL_AMT_ORDERED ELSE 0 END) AS '-3', --As MAX(dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTR) WHERE dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -3
SUM(CASE WHEN dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -2 THEN dbo.CUST_ORDER_LINE.TOTAL_AMT_ORDERED ELSE 0 END) AS '-2', --As MAX(dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTR) WHERE dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -2
SUM(CASE WHEN dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -1 THEN dbo.CUST_ORDER_LINE.TOTAL_AMT_ORDERED ELSE 0 END) AS '-1', --As MAX(dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTR) WHERE dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED = -1
SUM(CASE WHEN dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED IN(-4, -3, -2, -1) THEN dbo.CUST_ORDER_LINE.TOTAL_AMT_ORDERED ELSE 0 END) AS 'TOTAL'
FROM dbo.CUSTOMER_ORDER LEFT OUTER JOIN
dbo.UFC_Calander LEFT OUTER JOIN
dbo.UCC_CALENDAR_TODAY_BASED_AGING ON dbo.UFC_Calander.DAY = dbo.UCC_CALENDAR_TODAY_BASED_AGING.DATES ON
dbo.CUSTOMER_ORDER.ORDER_DATE = dbo.UFC_Calander.DAY LEFT OUTER JOIN
dbo.CUSTOMER ON dbo.CUSTOMER_ORDER.CUSTOMER_ID = dbo.CUSTOMER.ID RIGHT OUTER JOIN
dbo.PART RIGHT OUTER JOIN
dbo.CUST_ORDER_LINE ON dbo.PART.ID = dbo.CUST_ORDER_LINE.PART_ID ON dbo.CUSTOMER_ORDER.ID = dbo.CUST_ORDER_LINE.CUST_ORDER_ID
WHERE (dbo.CUSTOMER_ORDER.STATUS <> 'x') AND dbo.UCC_CALENDAR_TODAY_BASED_AGING.QTRs_AGED IN(-4, -3, -2, -1)
GROUP BY dbo.CUSTOMER_ORDER.CUSTOMER_ID
HAVING (dbo.CUSTOMER_ORDER.CUSTOMER_ID <> 'UNFOCO') AND (dbo.CUSTOMER_ORDER.CUSTOMER_ID <> 'QUOTE')
ORDER BY TOTAL DESC

Update a complex SQL query to add a new column with the sum of two columns

The below SQL query creates a table with n number of columns named in the next line.
...., curr_amount, tax_amount, ....
I am having a very tough time updating the below query to create a new column called total and position it exactly after tax_amount column and the total column should contain the values that are obtained after sum of curr_amount & tax_amount.
I have been working on this from more than one day but couldn't figure it out.
P.S. Still a noob here. Thanks alot for your time.
.
SELECT Isnull(t.total_month, 'Total') total_month,
t.tax_amount,
t.curr_amount,
t.usage_qty,
t.kh_qty,
t.bill_cnt
FROM (SELECT dbo.Sigmadf(bm.posted_date, 'YYYY-MM') total_month,
Sum(CASE
WHEN rr.usage_qty IS NULL THEN 0
ELSE Cast (rr.usage_qty AS NUMERIC(18, 2))
END) usage_qty,
Sum(CASE
WHEN bm.curr_amount IS NULL THEN 0
ELSE bm.curr_amount
END) curr_amount,
Sum(CASE
WHEN bm.adj_amount IS NULL THEN 0
ELSE bm.adj_amount
END) adj_amount,
Sum(CASE
WHEN bm.bal_fwd_amount IS NULL THEN 0
ELSE bm.bal_fwd_amount
END) bal_forward,
Sum(CASE
WHEN bm.tax_amount IS NULL THEN 0
ELSE bm.tax_amount
END) tax_amount,
Sum(CASE
WHEN bm.due_amount IS NULL THEN 0
ELSE bm.due_amount
END) due_amount,
Sum(CASE
WHEN bm.last_total_paid_amount IS NULL THEN 0
ELSE bm.last_total_paid_amount * -1
END) paid_amount,
Sum(CASE
WHEN bm.bill_print = 'Y' THEN 1
ELSE 0
END) pdf_cnt,
Sum(CASE
WHEN Isnull(bm.bill_handling_code, '0') = '0' THEN 1
ELSE 0
END) reg_cnt,
Sum(CASE
WHEN Isnull(bm.bill_handling_code, '0') = '1' THEN 1
ELSE 0
END) ftime_cnt,
Sum(CASE
WHEN Isnull(bm.bill_handling_code, '0') = '9999' THEN 1
ELSE 0
END) ltime_cnt,
Count(*) bill_cnt,
Sum(CASE
WHEN bill_status = '01' THEN 1
ELSE 0
END) canc_cnt,
Sum(CASE
WHEN bill_status = '01' THEN
CASE
WHEN rr.usage_qty IS NULL THEN 0
ELSE Cast (rr.usage_qty AS NUMERIC(18, 2))
END
ELSE 0
END) canc_usg,
Sum(CASE
WHEN vis.kh_qty IS NULL THEN 0
ELSE Cast(vis.kh_qty AS NUMERIC(18, 2))
END) kh_qty
FROM bill_master bm WITH (nolock)
INNER JOIN (SELECT bill_no,
Sum(CASE
WHEN vpb.recurr_charge_type IN ( 'T4',
'SLF' )
THEN
CASE
WHEN vpb.print_qty = 'Y'
AND vpb.usage_qty IS NOT NULL
THEN
Cast (vpb.usage_qty AS
NUMERIC(18, 2))
ELSE 0
END
ELSE 0
END) usage_qty
FROM v_print_bills_all vpb
GROUP BY bill_no) rr
ON rr.bill_no = bm.bill_no
LEFT OUTER JOIN vis_bill_master_cr vis WITH (nolock)
ON bm.bill_no = vis.bill_no
WHERE 1 = 1
AND dbo.Trunc(bm.posted_date) >= '20150101'
AND dbo.Trunc(bm.posted_date) <= '20151124'
AND bm.posted_date IS NOT NULL
AND bm.cust_id NOT IN (SELECT cc.code_type cust_id
FROM code_table cc WITH (nolock)
WHERE cc.code_tabname = 'RptExclCust'
AND cc.code_value = 'cust_id')
GROUP BY dbo.Sigmadf(bm.posted_date, 'YYYY-MM') WITH rollup)t
I must say that the explanation is not so clear.
From my understanding, you want the total of two columns.
So, wrap all your query between parenthesis, call it subQuery, and make the sum of the two columns on top:
SELECT subQuery.total_month as bill_date,
subQuery.curr_amount as amount,
subQuery.tax_amount tax,
subQuery.curr_amount + subQuery.tax_amount as [total],
...
FROM
(..your entire query here..) as subQuery

can not pivot table sql

i want to pivot table but i get some error about this image
this is my code
SELECT ARCBG_Abbrev
,ARCIM_Code
,SUM(CASE WHEN TAR_Code = 'O' THEN ITP_Price
ELSE 0 END) AS O
,SUM(CASE WHEN TAR_Code = 'I' THEN ITP_Price ELSE 0 END)
AS I
,SUM(CASE WHEN TAR_Code = 'F' THEN ITP_Price ELSE 0 END)
AS F
FROM SYSTEM.VS_OrderItem
WHERE (ARCIM_Code = '010004')
GROUP BY ARCBG_Abbrev, ARCIM_Code
i try to distinct column to check value in column is same in every row where ARCIM_Code = 010004 .it's the same value in column ARCBG_Abbrev. Can you check my pivot code plascc. thank you
on the assumption it's an ODBC driver limitation, perhaps nesting the case expressions as a subquery will help.
SELECT
ARCBG_Abbrev
, ARCIM_Code
, SUM(O) AS O
, SUM(I) AS I
, SUM(F) AS F
FROM (
SELECT
ARCBG_Abbrev
, ARCIM_Code
, CASE
WHEN TAR_Code = 'O' THEN
ITP_Price
ELSE
0
END AS O
, CASE
WHEN TAR_Code = 'I' THEN
ITP_Price
ELSE
0
END AS I
, CASE
WHEN TAR_Code = 'F' THEN
ITP_Price
ELSE
0
END AS F
FROM SYSTEM.VS_OrderItem
) AS SQ
WHERE ARCIM_Code = '010004'
GROUP BY
ARCBG_Abbrev
, ARCIM_Code