How to Group This SQL - mysql

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;

Related

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

Syntax error with Complex MySQL Procedure/Function

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

Create View displays differently than the select

I am trying to create a view and the select statement is exactly what I want to see, but when I use that exact same select statement as the create view statement its parses the information differently. Here is the select statement.
CREATE VIEW shippingview
AS
( SELECT shipcarton.id AS shipcartonid
,ship.num AS shipnum
,so.num AS sonum
,so.customerpo AS customerpo
,so.email AS email
,so.phone AS phone
,countryconst.abbreviation AS country
,stateconst.code AS STATE
,ship.shiptozip AS postalcode
,ship.shiptocity AS city
,carrierservice.name AS servicename
,carrierservice.code AS servicecode
,shipcarton.freightweight AS weight
,shipcarton.len AS length
,shipcarton.height AS height
,shipcarton.width AS width
,`ship`.`id` AS `shipID`
,(
CASE
WHEN (locate('\n', `ship`.`shipToAddress`) > 0)
THEN substr(`ship`.`shipToAddress`, 1, (locate('\n', `ship`.`shipToAddress`) - 1))
ELSE `ship`.`shipToAddress`
END
) AS `SHIPTOADDRESS1`
,(
CASE
WHEN (
(locate('\n', `ship`.`shipToAddress`) > 0)
AND (locate('\n', `ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`) + 1)) = 0)
)
THEN substr(`ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`) + 1))
WHEN (
(locate('\n', `ship`.`shipToAddress`) > 0)
AND (locate('\n', `ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`) + 1)) > 0)
)
THEN substr(`ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`) + 1), (locate('\n', `ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`) + 1)) - (locate('\n', `ship`.`shipToAddress`) + 1)))
ELSE ''
END
) AS `SHIPTOADDRESS2`
,(
CASE
WHEN (locate('\n', `ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`) + 1)) > 0)
THEN substr(`ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`, (locate('\n', `ship`.`shipToAddress`) + 1)) + 1))
ELSE ''
END
) AS `SHIPTOADDRESS3`
FROM ship
LEFT JOIN so ON ship.soid = so.id
LEFT JOIN carrierservice ON ship.carrierserviceid = carrierservice.id
LEFT JOIN countryconst ON ship.shiptocountryid = countryconst.id
LEFT JOIN stateconst ON ship.shiptostateid = stateconst.id
LEFT JOIN shipcarton ON shipcarton.shipid = ship.id
WHERE ship.statusid IN (
10
,20
)
)
It supposed to display address seperated by line breaks and it works completely correctly as the select and not the create.

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

PIVOT data in mysql

RCDID, EmployeeID, LogDate, LogTime, TerminalID, InOut, read
3079184, 'A00075', '2009/10/28', '07:17:10 ', 'VC01 ', 'IN ', '1'
3079185, 'A00075', '2009/10/28', '17:28:51 ', 'VC01 ', 'OUT ', '1'
3079186, 'A00038', '2009/10/28', '07:29:17 ', 'VC01 ', 'IN ', '1'
3079187, 'A00038', '2009/10/28', '17:30:05 ', 'VC01 ', 'OUT ', '1'
3079188, 'A00085', '2009/10/28', '07:37:34 ', 'VC01 ', 'IN ', '1'
3079189, 'A00085', '2009/10/28', '17:43:14 ', 'VC01 ', 'IN ', '1'
Hi, above is my source table (mysql) i want to cross tab the data as follows.
EmployeeID, LogDate, In_location, in_time, Out_location, Out_time
'A00001', '2009/10/28', 'VC01', '08:37:55 ', '', '',
'A00001', '2009/10/29', 'VC01', '08:09:57 ', 'VC01 ', '17:09:32 '
'A00001', '2009/10/30', 'VC01 ', '09:48:41 ', 'VC01 ', '20:40:37 '
'A00001', '2009/11/03', 'VC01', '08:20:34 ', 'VC01 ', '18:03:34 '
'A00001', '2009/11/04', 'VC01 ', '08:26:49 ', 'VC01 ', '19:21:46 '
'A00001', '2009/11/05', 'VC01', '08:16:00 ', 'VC01 ', '19:26:01 '
can somebody help me please. i am really appreciate your help
Essentially, one needs to perform a self-join to pair up movements IN with the following OUT by the same employee on the same date:
SELECT a.EmployeeID, a.LogDate,
a.LogTime AS In_time,
MIN(b.LogTime) AS Out_time
FROM my_table a LEFT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND b.InOut = 'OUT'
WHERE a.InOut = 'IN'
GROUP BY EmployeeID, LogDate, In_time
However, this excludes situations where there is an IN record with no corresponding OUT record. Since MySQL has no native support for FULL OUTER JOIN, one must instead use UNION to combine the above with a similar query that pairs movements OUT with the preceding IN by the same employee on the same date:
SELECT a.EmployeeID, a.LogDate,
a.LogTime AS In_time,
MIN(b.LogTime) AS Out_time
FROM my_table a LEFT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND b.InOut = 'OUT'
WHERE a.InOut = 'IN'
GROUP BY EmployeeID, LogDate, In_time
UNION
SELECT a.EmployeeID, a.LogDate,
MAX(a.LogTime) AS In_time,
b.LogTime AS Out_time
FROM my_table a RIGHT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND a.InOut = 'IN'
WHERE b.InOut = 'OUT'
GROUP BY EmployeeID, LogDate, Out_time
Having obtained this detail, one then needs to join the result with the table again in order to extract the terminals on which the movements were logged:
SELECT t.EmployeeID,
t.LogDate,
a.TerminalID AS In_location,
t.In_time,
b.TerminalID AS Out_location,
t.Out_time
FROM (
SELECT a.EmployeeID, a.LogDate,
a.LogTime AS In_time,
MIN(b.LogTime) AS Out_time
FROM my_table a LEFT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND b.InOut = 'OUT'
WHERE a.InOut = 'IN'
GROUP BY EmployeeID, LogDate, In_time
UNION
SELECT a.EmployeeID, a.LogDate,
MAX(a.LogTime) AS In_time,
b.LogTime AS Out_time
FROM my_table a RIGHT JOIN my_table b ON
a.EmployeeID = b.EmployeeID
AND a.LogDate = b.LogDate
AND a.LogTime < b.LogTime
AND a.InOut = 'IN'
WHERE b.InOut = 'OUT'
GROUP BY EmployeeID, LogDate, Out_time
) t
LEFT JOIN my_table a ON
a.EmployeeID = t.EmployeeID
AND a.LogDate = t.LogDate
AND a.LogTime = t.In_time
AND a.InOut = 'IN'
LEFT JOIN my_table b ON
b.EmployeeID = t.EmployeeID
AND b.LogDate = t.LogDate
AND b.LogTime = t.Out_time
AND b.InOut = 'OUT'
See it on sqlfiddle.