Syntax error with Complex MySQL Procedure/Function - mysql
I have come up with a fairly complex query that computes and returns two date fields based on some input arguments. These date values need to be further used in a report which will have lots of other fields. As you can see there are 4 input variables and 2 output variables.
set #caSplit = 0.3;
set #flSplit = 0.7;
set #formulaForAvgUsed='useAvgOfAll';
set #itemNumber = 'TAB_120_IVR_POLY';
select
max(case when compCA >0 then rollingDate else current_date end) as oosDateForCA,
max(case when compFL >0 then rollingDate else current_date END) as oosDateForFL
from
(
select
items.item, items.rollingDate, perDaySalesCA, perDaySalesFL,
items.total_items_in_ca, total_items_in_fl, flAsnItems.flASNQty, caAsnItems.caASNQty,
#prevDayCA := case
when cntr = 0 then total_items_in_ca
when greatest(#prevDayCA,0) + coalesce(caASNQty,0) = 0 then 0
else greatest(#prevDayCA,0) - perDaySalesCA - IF(#prevDayFL > perDaySalesFL, 0, perDaySalesFL) + coalesce(caASNQty,0)
end as compCA,
#prevDayCA as caInv,
#prevDayFL := case
when cntr = 0 then total_items_in_fl
when greatest(#prevDayFL,0) + coalesce(flASNQty,0) = 0 then 0
else greatest(#prevDayFL,0) - perDaySalesFL - IF(#prevDayCA > perDaySalesCA, 0, perDaySalesCA) + coalesce(flAsnQty, 0)
end as compFL,
#prevDayFL as flInv
from
(select #prevDayCA := -1, #prevDayFL := -1)vars,
(
select
item, total_items_in_fl, total_items_in_ca,
ROUND(avgToUse * #caSplit / 30) as perDaySalesCA,
ROUND(avgToUse * #flSplit / 30) as perDaySalesFL,
#cntr as cntr,
DATE_ADD(current_date, INTERVAL #cntr DAY) as rollingDate,
#cntr := #cntr + 1
from
(
select
#cntr := 0
) vars
join counter c
join
(
select
i.number as item, i.total_items_in_ca, i.total_items_in_fl,
case when #formulaForAvgUsed = 'useNewMSA' then
i.new_msa
when #formulaForAvgUsed = 'useMSA' then
i.monthly_sales_average
when #formulaForAvgUsed = 'useWMSA' then
i.weighted_monthly_sales_average
when #formulaForAvgUsed = 'useTwoWeeks' then
i.two_wks_average * 2
when #formulaForAvgUsed = 'useMaxAvg' then
greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2)
when #formulaForAvgUsed = 'useAvgOfAll' then
case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) > CURRENT_DATE then
(i.new_msa + i.two_wks_average *2 + i.monthly_sales_average)/3
else
(i.new_msa + i.two_wks_average *2 + i.monthly_sales_average+ i.weighted_monthly_sales_average)/4
end
when #formulaForAvgUsed = 'useAvgMSAAndNewMSA' then
(i.new_msa + i.monthly_sales_average)/2
when #formulaForAvgUsed = 'useAvgWMSAAndTwoWeeks' then
case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) < CURRENT_DATE then
i.weighted_monthly_sales_average
else
( i.two_wks_average *2 + i.weighted_monthly_sales_average)/2
end
else
greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2)
end as avgToUse
from
item i
where
i.number = #itemNumber
) T
) items
left join
(
select
i.number, date(estimated_arrival_date) as asnDate,
sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as caASNQty
from
item i join asn_order_line aol on aol.item_id = i.item_id
join asn_order ao on ao.asn_order_id = aol.asn_order_id
join pack p on aol.pack_id = p.pack_id
where
aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received')
and facility = 'WHSE'
and i.number = #itemNumber
group by
i.number, date(estimated_arrival_date)
) caAsnItems on caAsnItems.number = items.item and caAsnItems.asnDate = rollingDate
left join
(
select
i.number,
date(estimated_arrival_date) as asnDate,
sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as flASNQty
from
item i join asn_order_line aol on aol.item_id = i.item_id
join asn_order ao on ao.asn_order_id = aol.asn_order_id
join pack p on aol.pack_id = p.pack_id
where
aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received')
and facility = 'FLOR'
and i.number = #itemNumber
group by
i.number, date(estimated_arrival_date)
) flAsnItems on flAsnItems.number = items.item and flAsnItems.asnDate = rollingDate
group by
rollingDate
having
caInv > 0 || flInv > 0
|| rollingDate <= greatest(max(flAsnItems.asnDate), max(caAsnItems.asnDate))
order by
rollingDate DESC
)top;
My intent is to create a procedure and select the values in the top level into the output variables. Using MySQL Workbench when I try to create with this syntax, it throws a syntax error but doesn't say what exactly is the issue.
DELIMITER //
CREATE PROCEDURE `compute_oos_date2` (IN itemNumber VARCHAR(50), IN formulaForAvgUsed VARCHAR(50), IN caSplit FLOAT, IN flSplit FLOAT, OUT oosDateForCA DATE, OUT oosDateForFL DATE)
BEGIN
SET #prevDayCA = -1;
SET #prevDayFL = -1;
select
max(case when compCA >0 then rollingDate else current_date end) into oosDateForCA,
max(case when compFL >0 then rollingDate else current_date END) into oosDateForFL
from
(
select
items.item, items.rollingDate, perDaySalesCA, perDaySalesFL,
items.total_items_in_ca, total_items_in_fl, flAsnItems.flASNQty, caAsnItems.caASNQty,
#prevDayCA := case
when cntr = 0 then total_items_in_ca
when greatest(#prevDayCA,0) + coalesce(caASNQty,0) = 0 then 0
else greatest(#prevDayCA,0) - perDaySalesCA - IF(#prevDayFL > perDaySalesFL, 0, perDaySalesFL) + coalesce(caASNQty,0)
end as compCA,
#prevDayCA as caInv,
#prevDayFL := case
when cntr = 0 then total_items_in_fl
when greatest(#prevDayFL,0) + coalesce(flASNQty,0) = 0 then 0
else greatest(#prevDayFL,0) - perDaySalesFL - IF(#prevDayCA > perDaySalesCA, 0, perDaySalesCA) + coalesce(flAsnQty, 0)
end as compFL,
#prevDayFL as flInv
from
(
select
item, total_items_in_fl, total_items_in_ca,
ROUND(avgToUse * caSplit / 30) as perDaySalesCA,
ROUND(avgToUse * flSplit / 30) as perDaySalesFL,
#cntr as cntr,
DATE_ADD(current_date, INTERVAL #cntr DAY) as rollingDate,
#cntr := #cntr + 1
from
(select #cntr := 0) vars
join counter c
join
(
select
i.number as item, i.total_items_in_ca, i.total_items_in_fl,
case when formulaForAvgUsed = 'useNewMSA' then
i.new_msa
when formulaForAvgUsed = 'useMSA' then
i.monthly_sales_average
when formulaForAvgUsed = 'useWMSA' then
i.weighted_monthly_sales_average
when formulaForAvgUsed = 'useTwoWeeks' then
i.two_wks_average * 2
when formulaForAvgUsed = 'useMaxAvg' then
greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2)
when formulaForAvgUsed = 'useAvgOfAll' then
case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) > CURRENT_DATE then
(i.new_msa + i.two_wks_average *2 + i.monthly_sales_average)/3
else
(i.new_msa + i.two_wks_average *2 + i.monthly_sales_average+ i.weighted_monthly_sales_average)/4
end
when formulaForAvgUsed = 'useAvgMSAAndNewMSA' then
(i.new_msa + i.monthly_sales_average)/2
when formulaForAvgUsed = 'useAvgWMSAAndTwoWeeks' then
case when DATE_ADD(i.first_sold_date, INTERVAL 365 DAY) < CURRENT_DATE then
i.weighted_monthly_sales_average
else
( i.two_wks_average *2 + i.weighted_monthly_sales_average)/2
end
else
greatest(i.new_msa, i.monthly_sales_average, i.weighted_monthly_sales_average, i.two_wks_average *2)
end as avgToUse
from
item i
where
i.number = itemNumber
) T
) items
left join
(
select
i.number, date(estimated_arrival_date) as asnDate,
sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as caASNQty
from
item i join asn_order_line aol on aol.item_id = i.item_id
join asn_order ao on ao.asn_order_id = aol.asn_order_id
join pack p on aol.pack_id = p.pack_id
where
aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received')
and facility = 'WHSE'
and i.number= itemNumber
group by
i.number, date(estimated_arrival_date)
) caAsnItems on caAsnItems.number = items.item and caAsnItems.asnDate = rollingDate
left join
(
select
i.number,
date(estimated_arrival_date) as asnDate,
sum((aol.loaded_quantity - aol.received_Quantity) * p.quantity) as flASNQty
from
item i join asn_order_line aol on aol.item_id = i.item_id
join asn_order ao on ao.asn_order_id = aol.asn_order_id
join pack p on aol.pack_id = p.pack_id
where
aol.line_status = 'New' and ao.status in ('New' , 'Partial Receipt', 'Receiving', 'Partially Received')
and facility = 'FLOR'
and i.number = itemNumber
group by
i.number, date(estimated_arrival_date)
) flAsnItems on flAsnItems.number = items.item and flAsnItems.asnDate = rollingDate
group by
rollingDate
having
caInv > 0 || flInv > 0
|| rollingDate <= greatest(max(flAsnItems.asnDate), max(caAsnItems.asnDate))
order by
rollingDate DESC
)top
END //
DELIMITER;
Can anyone help ?
I figured out , the syntax to load into multiple variables is
select 'abc', 'def' into var1, var2
Earlier I was using
select 'abc' into var1, 'def' into var2
Related
Snowflake Function input is datetime, but when i call the function it's not quite working
with temp AS ( SELECT CAST(SUM(sreg.ScrapQuantity) AS INT) AS Quantity, sreas.Name AS ScrapReason, to_date((DATEADD(MINUTE, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, TIMESTAMPDIFF(HOUR, '0', sreg.ScrapTime), '0')))) AS DATETIME, sreg.EquipmentID AS EquipmentID FROM ScrapRegistration sreg INNER JOIN ScrapReason sreas ON sreas.ID = sreg.ScrapReasonID INNER JOIN WorkRequest wr ON wr.ID = sreg.WorkRequestID INNER JOIN SegmentRequirementEquipmentRequirement srer ON srer.SegmentRequirementID = wr.SegmentRequirementID GROUP BY DATEADD(MINUTE, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, TIMESTAMPDIFF(HOUR, '0', sreg.ScrapTime), '0')), sreg.EquipmentID, sreas.Name ) select temp.EquipmentID from RAW_CPMS_AAR.equipment e, temp Where e.ID = (select * from table(cfn_GetShiftIDFromDateTime_test(temp.DateTime::DATETIME, 0))) --this works with datetime when i run this query above, i get Processing aborted due to error 300010:391167117; incident 3245754.. I believe this is an issue with the temp.datetime -- when i run the same codebut hardcoding the function input, i get the desired output. with temp AS ( SELECT CAST(SUM(sreg.ScrapQuantity) AS INT) AS Quantity, sreas.Name AS ScrapReason, to_date((DATEADD(MINUTE, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, TIMESTAMPDIFF(HOUR, '0', sreg.ScrapTime), '0')))) AS DATETIME, sreg.EquipmentID AS EquipmentID FROM ScrapRegistration sreg INNER JOIN ScrapReason sreas ON sreas.ID = sreg.ScrapReasonID INNER JOIN WorkRequest wr ON wr.ID = sreg.WorkRequestID INNER JOIN SegmentRequirementEquipmentRequirement srer ON srer.SegmentRequirementID = wr.SegmentRequirementID GROUP BY DATEADD(MINUTE, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, TIMESTAMPDIFF(HOUR, '0', sreg.ScrapTime), '0')), sreg.EquipmentID, sreas.Name ) select temp.EquipmentID from RAW_CPMS_AAR.equipment e, temp Where e.ID = (select * from table(cfn_GetShiftIDFromDateTime_test('2021-12-02 10:03:0.00'::datetime, 0))) --this works with datetime it seems that that somwehere along the line, it's not liking the date format i put in. it's not returning me an error of not liking the input. here is the function. CREATE OR REPLACE FUNCTION DB_BI_DEV.RAW_CPMS_AAR.cfn_GetShiftIDFromDateTime (dateTime TIMESTAMP_NTZ(9), shiftCalendarID int) RETURNS table (shiftID int) AS $$ WITH T0 (ShiftCalendarID, CurDay, PrvDay) AS ( SELECT TOP 1 ID AS ShiftCalendarID, DATEDIFF( day, BeginDate, dateTime ) % PeriodInDays + 1 AS CurDay, ( CurDay + PeriodInDays - 2 ) % PeriodInDays + 1 AS PrvDay FROM RAW_CPMS_AAR.ShiftCalendar WHERE ID = shiftCalendarID OR ( shiftCalendarID IS NULL AND Name = 'Factory' AND BeginDate <= dateTime ) ORDER BY BeginDate DESC ), T1 (TimeValue) AS ( SELECT TIME_FROM_PARTS( EXTRACT(HOUR FROM dateTime), EXTRACT(MINUTE FROM dateTime), EXTRACT(SECOND FROM dateTime)) ) SELECT ID as shiftID FROM RAW_CPMS_AAR.Shift, T0, T1 WHERE Shift.ShiftCalendarID = T0.ShiftCalendarID AND ( ( FromDay = T0.CurDay AND FromTimeOfDay <= T1.TimeValue AND TillTimeOfDay > T1.TimeValue ) OR ( FromDay = T0.CurDay AND FromTimeOfDay >= TillTimeOfDay AND FromTimeOfDay <= T1.TimeValue ) OR ( FromDay = T0.PrvDay AND FromTimeOfDay >= TillTimeOfDay AND TillTimeOfDay > T1.TimeValue ) ) $$ ;
SQLSERVER Running Balance
Actually i have problem on my query to get the running balance , i have debit and credit transaction i need one column to showing the cumulative running balance this is the code i used : Select * From ( Select D.AccNo, H.[Date], A.AccountName, H.TrxNo, (Case When ((D.Remark = '') or (D.Remark is Null)) Then H.Trxnote Else D.Remark End) As TrxDetailDescA, (D.Debit * 1) AS DebitValue, (D.Credit * 1) AS CreditValue,SUM(COALESCE(D.Debit, 0) - COALESCE(D.Credit, 0)) AS Balance From TblHeadTrans H, TblTransDetails D, TblAccount A Where H.Guid = D.[LineNo] And D.AccNo = A.AccountNo And H.[Date] >= '01-01-2022' And H.[Date] <= '10-07-2022' And D.AccNo >= '1003' group by AccNo,H.[Date],A.AccountName,H.TrxNo,D.Remark,h.Trxnote,d.Debit,d.Credit Union All Select D.AccNo, Null As TrxDate, A.AccountName, Null As TrxNo, 'Opening Balance' As TrxDetailDesc, Case When (Sum(D.Debit * 1) - Sum(D.Credit *1)) < 0 then 0 Else (Sum(D.Debit * 1) - Sum(D.Credit * 1)) End As DebitValue, Case When (Sum(D.Credit * 1) - Sum(D.Debit * 1)) < 0 then 0 Else (Sum(D.Credit * 1) - Sum(D.Debit * 1)) End As CreditValue , SUM(COALESCE(d.Debit, 0) - COALESCE(d.credit, 0)) AS Balance From TblHeadTrans H, TblTransDetails D, TblAccount A Where H.guid = D.[LineNo] And D.AccNo = A.AccountNo And d.[Date] < '01-01-2022' And D.accno = '1003' Group By D.AccNo, A.AccountName,H.Date,H.TrxNo ) ReportData WHERE 1=1 Order By AccNo, [Date], TrxNo and the result showing as the picture: the result
How to Group This SQL
The SQL statement below produce sums of data for months and displays the columns as years. The problem, as you will see in the image below, is that the result set has null values. Is there a way to represent the dataset for each month once? SELECT DATE_FORMAT(start_date, '%M') AS M, (CASE DATE_FORMAT(start_date, '%Y') WHEN 2015 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2015', (CASE DATE_FORMAT(start_date, '%Y') WHEN 2016 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2016', (CASE DATE_FORMAT(start_date, '%Y') WHEN 2017 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2017', (CASE DATE_FORMAT(start_date, '%Y') WHEN 2018 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2018' FROM phases_required b RIGHT JOIN projects a ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, ROUND(reimbursable_percent, 0) AS percentage FROM rate_names t1, phases_required t2, rates_phase t3 WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id GROUP BY t2.project_id) AS pcntg ON pcntg.project_id = a.id WHERE start_date != '0000-00-00' AND DATE_FORMAT(start_date, '%Y') NOT IN (2010 , 2012, 2013, 2014) GROUP by DATE_FORMAT(start_date, '%m%Y') Here is the SQL to produce the table SQL statement you see above dynamically: SET SESSION group_concat_max_len = 10000000000; SET #sqldynamic = ( SELECT GROUP_CONCAT( distinct CONCAT( '(case date_format(start_date,"%Y") when ', date_format(a.start_date,"%Y") , ' then ROUND((COALESCE(sum(b.bid_amount), 0) + COALESCE(sum(b.hourly_bid_amount),0) + COALESCE(sum(b.other_bid_amount), 0) * pcntg.percentage/100 + sum(b.other_bid_amount) - COALESCE(sum(b.subcontracted_amount),0)),2)+COALESCE(sum(b.subcontracted_amount),0)+COALESCE(sum(b.contingency_1),0) end) as \'' , date_format(start_date,"%Y"),'\'' ) ) From phases_required b RIGHT JOIN projects a ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3 WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) ); SET #sql = CONCAT('SELECT date_format(start_date,"%M") as M, ', #sqldynamic, ' From phases_required b RIGHT JOIN projects a ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3 WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) group by date_format(start_date,"%M%Y") order by date_format(start_date,"%m")' ); PREPARE stmt FROM #sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
I don't like but it should works : select m, sum(coalesce('2015', 0)) '2015', sum(coalesce('2015', 0)) '2016', sum(coalesce('2015', 0)) '2017', sum(coalesce('2015', 0)) '2018' from ( SELECT DATE_FORMAT(start_date, '%M') AS M, (CASE DATE_FORMAT(start_date, '%Y') WHEN 2015 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2015', (CASE DATE_FORMAT(start_date, '%Y') WHEN 2016 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2016', (CASE DATE_FORMAT(start_date, '%Y') WHEN 2017 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2017', (CASE DATE_FORMAT(start_date, '%Y') WHEN 2018 THEN ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)), 2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0) END) AS '2018' FROM phases_required b RIGHT JOIN projects a ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, ROUND(reimbursable_percent, 0) AS percentage FROM rate_names t1, phases_required t2, rates_phase t3 WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id GROUP BY t2.project_id) AS pcntg ON pcntg.project_id = a.id WHERE start_date != '0000-00-00' AND DATE_FORMAT(start_date, '%Y') NOT IN (2010 , 2012, 2013, 2014) GROUP by DATE_FORMAT(start_date, '%m%Y') ) qry group by m;
Here is the answer. Thank you Daniel Blais for helping getting me here. SET SESSION group_concat_max_len = 10000000000; SET #sqldynamic = ( SELECT GROUP_CONCAT( distinct CONCAT( '(case date_format(start_date,"%Y") when ', date_format(a.start_date,"%Y") , ' then ROUND((COALESCE(sum(b.bid_amount), 0) + COALESCE(sum(b.hourly_bid_amount),0) + COALESCE(sum(b.other_bid_amount), 0) * pcntg.percentage/100 + sum(b.other_bid_amount) - COALESCE(sum(b.subcontracted_amount),0)),2)+COALESCE(sum(b.subcontracted_amount),0)+COALESCE(sum(b.contingency_1),0) end) as Y_' , date_format(start_date,"%Y") ) ) From phases_required b RIGHT JOIN projects a ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3 WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) ); SET #sqlgroup = ( SELECT GROUP_CONCAT(distinct CONCAT('sum(coalesce(Y_', date_format(a.start_date,"%Y") ,', 0)) as Y_',date_format(a.start_date,"%Y") ) ) From phases_required b RIGHT JOIN projects a ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3 WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) ); SET #sql = CONCAT('select m,', #sqlgroup , ' from (SELECT date_format(start_date,"%M") as M, date_format(start_date,"%m") as m2 ,', #sqldynamic, ' From phases_required b RIGHT JOIN projects a ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3 WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) group by date_format(start_date,"%M%Y") order by date_format(start_date,"%m")) qry group by m order by m2' ); PREPARE stmt FROM #sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
sql query with DISTINCT make huge performance issue
i have a query to get summary of donations SELECT CONVERT(CHAR(2), CAST(pb.PayrollDate AS DATETIME), 101) + '/' + CONVERT(CHAR(4), CAST(pb.PayrollDate AS DATETIME), 120) AS Closing_Month , CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112) AS Closing_Year , COUNT(DISTINCT Donation.Employee) + ( SELECT COUNT(*) FROM dbo.Donation INNER JOIN PayrollBatch pbd ON Donation.PayrollBatch = pbd.ID WHERE CONVERT(CHAR(6), CAST(pbd.PayrollDate AS DATETIME), 112) = CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112) AND DonationType = 5 )AS 'Donors' , COUNT (DISTINCT( CASE WHEN Donation.DonationType = 1 OR Donation.DonationType = 5 THEN CharityDetails.ID END ))AS 'Charities', ( CAST(COUNT(DISTINCT Donation.Employee) AS DECIMAL(18, 2)) / ( SELECT SUM(NumberOfEmployees) FROM OrganisationDetail WHERE ID = Donation.OrganisationDetail AND IsDeleted = 0 ) ) * 100 AS 'Participation_Rate' , SUM(CASE WHEN Donation.DonationType = 1 OR Donation.DonationType = 5 THEN Donation.Amount ELSE 0 END) AS 'Employee_Donations' , SUM(CASE WHEN Donation.DonationType = 2 THEN Donation.Amount ELSE 0 END) AS 'Matched_Donations' , SUM(CASE WHEN Donation.DonationType = 1 OR Donation.DonationType = 2 OR Donation.DonationType = 5 THEN Donation.Amount ELSE 0 END) AS 'Total_Donations' FROM Donation INNER JOIN OrganisationDetail AS OrganisationDetail_1 ON Donation.OrganisationDetail = OrganisationDetail_1.ID INNER JOIN CharityProjectDetails ON Donation.CharityProjectDetails = CharityProjectDetails.ID INNER JOIN CharityDetails ON CharityProjectDetails.CharityDetails = CharityDetails.ID INNER JOIN PayrollBatch pb ON Donation.PayrollBatch = pb.ID LEFT JOIN Employee ON Donation.Employee = Employee.ID LEFT JOIN DonationIntent ON Donation.DonationIntent = DonationIntent.ID LEFT JOIN EmployeeAddress ON Employee.ID = EmployeeAddress.Employee LEFT JOIN dbo.PayrollBatchOther pbo ON pbo.PayrollBatch = pb.ID GROUP BY CONVERT(CHAR(2), CAST(pb.PayrollDate AS DATETIME), 101) + '/' + CONVERT(CHAR(4), CAST(pb.PayrollDate AS DATETIME), 120) , CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112) , Donation.OrganisationDetail ORDER BY Closing_Year; i need to get unique donors count from result set COUNT(DISTINCT e.ID) but with distinct query takes 7-9 sec to complete execution but without that it took only 1 sec how to improve that performance Update Here is the Paste The Plan
how to use clause(where,and,not) sql
I have table absen like this: and the table itungharian with coloumn like this: id_itung | id | total | itungtgl (no data) and query join like this: SELECT count(tgl) AS total, absen.id, pegawai.nama, pegawai.bagian, pegawai.bagian, pegawai.tglmasuk, gaji.jenis_gaji, gaji.jumlah, itungharian.id AS id2, itungharian.itungtgl, CASE WHEN (weekday(tgl) <=3 ) THEN date(tgl + INTERVAL(3 - weekday(tgl)) DAY) ELSE date(tgl + INTERVAL(3 + 7 - weekday(tgl)) DAY) END AS tglitung FROM absen JOIN pegawai ON pegawai.id = absen.id JOIN gaji ON gaji.id = pegawai.id LEFT JOIN itungharian ON itungharian.id = absen.id WHERE absen.status = 'm' GROUP BY absen.id, tglitung and show this So I have problem how to join like this if values on cloumn id(table absen) same with itungharian.tgl and tglitung(result case when) same with itungharian.itungtgl don't show in join table I have tried with sql like this: SELECT count(tgl) AS total, absen.id, pegawai.nama, pegawai.bagian, pegawai.bagian, pegawai.tglmasuk, gaji.jenis_gaji, gaji.jumlah, itungharian.id AS id2, itungharian.itungtgl, CASE WHEN (weekday(tgl) <= 3) THEN date(tgl + INTERVAL(3 - weekday(tgl)) DAY) ELSE date(tgl + INTERVAL(3 + 7 - weekday(tgl)) DAY) END AS tglitung FROM absen JOIN pegawai ON pegawai.id = absen.id JOIN gaji ON gaji.id = pegawai.id LEFT JOIN itungharian ON itungharian.id = absen.id WHERE absen.status = 'm' AND NOT (CASE WHEN (weekday(tgl) <= 3) THEN DATE(tgl + INTERVAL(3 - weekday(tgl)) DAY) ELSE DATE(tgl + INTERVAL(3 + 7 - weekday(tgl)) DAY)END) = itungharian.itungtgl AND NOT absen.id = itungharian.id GROUP BY absen.id, tglitung but MySQL returned an empty result set (i.e. zero rows).