SUM selected columns using alias and group by - mysql

I'm trying to perform calculations on select columns using aliases and a grouping by. Query is below(problem on line before the from):
select r.res_id,
r.arrive_date,
r.depart_date,
r.res_type,
if(DATEDIFF(r.depart_date, r.arrive_date) >29, 'LT', 'ST') as 'StayType',
SUM(r.rent + r.fee_arr_early + r.fee_dep_late + r.fee_peace_waiver + r.fee_pool + r.city_tax + r.fee_cleaning + r.fee_pet + r.fee_tshirt + r.fee_misc + r.fee_non_tax + r.fee_processing + r.fee_travel_ins + r.fee_event + r.fee_cancel) as 'folioTotal',
coalesce((select SUM(g.amount) from guest_payments as g where g.resId = r.res_id and charge_type = 'charge' and approved = 'Y'),0) as 'payments',
coalesce((select SUM(g.amount) from guest_payments as g where g.resId = r.res_id and charge_type = 'credit' and approved = 'Y'),0) as 'credits',
(SUM('folioTotal') - SUM('payments') + SUM('credits')) as 'folioBalance'
from reservations as r
join guest_payments as g
on r.res_id = g.resId
group by r.res_id
I've tried putting this inside another sum with the same outcome.

I was being stupid, I was referencing the aliases inside single ticks which is why it wasn't calculating. Solution:
select r.res_id,
r.arrive_date,
r.depart_date,
r.res_type,
g.entry_date,
if(DATEDIFF(r.depart_date, r.arrive_date) >29, 'LT', 'ST') as 'StayType',
(select SUM(r.rent + r.fee_arr_early + r.fee_dep_late + r.fee_peace_waiver + r.fee_pool + r.city_tax + r.fee_cleaning + r.fee_pet + r.fee_tshirt + r.fee_misc + r.fee_non_tax + r.fee_processing + r.fee_travel_ins + r.fee_event + r.fee_cancel) from reservations as r where r.res_id = g.resId) as 'folioTotal',
coalesce((select SUM(g.amount) from guest_payments as g where g.resId = r.res_id and charge_type = 'charge' ),0) as 'payments',
coalesce((select SUM(g.amount)* -1 from guest_payments as g where g.resId = r.res_id and charge_type = 'credit' and approved = 'Y'),0) as 'credits',
(select folioTotal - payments + credits)
from reservations as r
join guest_payments as g
on r.res_id = g.resId
group by r.res_id

Related

SQL - Group and count duplicates row

I have no idea how to group and count duplicates row on mysql
below is the result that I got from my query
ssn + checktime + nama
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'196702031989031001' + '2018-08-03 07:33:02' + 'FAJAR PERMADI'
'196810021993031001' + '2018-08-01 07:33:25' + 'ANDRI ANGGORO, SH'
'196911052000031001' + '2018-08-03 07:47:22' + 'SEMI TEDDY RORY, SS'
'196912221994032001' + '2018-08-01 08:03:59' + 'AI SALATUN'
'196912221994032001' + '2018-08-02 09:34:11' + 'AI SALATUN'
'196912221994032001' + '2018-08-03 07:33:18' + 'AI SALATUN'
'197012051993031001' + '2018-08-01 07:58:47' + 'AHMAD SODIKIN, SH'
'197012192001121001' + '2018-08-01 09:54:21' + 'JUARA PAHALA MARBUN, ST'
'197012192001121001' + '2018-08-02 09:39:41' + 'JUARA PAHALA MARBUN, ST'
and below is my query
SELECT a.ssn, a.checktime, b.nama
FROM hki_kepegawaian.fo_absensi a
left join hki_kepegawaian.fo_pegawai b on a.ssn = b.nip
where (substring(cast(checktime as DATE), 6, 2) = '08')
and (cast(a.checktime as TIME)) >= '07:30:00' and (cast(a.checktime as
TIME)) <= '10:00:00'
and (substring(golongan, 1, 2)) NOT IN ('IV')
group by ssn, cast(a.checktime as date)
and below is result that I expected
ssn + checktime + nama + total
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'196702031989031001' + '2018-08-03 07:33:02' + 'FAJAR PERMADI' + 1
'196810021993031001' + '2018-08-01 07:33:25' + 'ANDRI ANGGORO, SH' + 1
'196911052000031001' + '2018-08-03 07:47:22' + 'SEMI TEDDY RORY, SS' + 1
'196912221994032001' + '2018-08-01 08:03:59' + 'AI SALATUN' + 3
'197012051993031001' + '2018-08-01 07:58:47' + 'AHMAD SODIKIN, SH' + 1
'197012192001121001' + '2018-08-01 09:54:21' + 'JUARA PAHALA MARBUN, ST' + 2
Your expected output implies that you want to report the record having the earliest check time for each ssn/nama group of records. For the count, it just looks like the total number of records in each group.
SELECT
a.ssn,
MIN(CAST(a.checktime AS date)) AS checktime,
b.nama,
COUNT(*) AS total
FROM hki_kepegawaian.fo_absensi a
LEFT JOIN hki_kepegawaian.fo_pegawai b
ON a.ssn = b.nip
WHERE
MONTH(checktime) = 8 AND
CAST(a.checktime AS TIME) BETWEEN '07:30:00' AND '10:00:00' AND
SUBSTRING(golongan, 1, 2)) <> 'IV'
GROUP BY
a.ssn, CAST(a.checktime AS date);
I agree with Tim that you seem to want to take the earliest time. This is accomplished with a group by in this case.
However, there are some other fixes to the query that I would suggest:
Do not use string operations on date/times.
Use meaningful table aliases that are abbreviations for the table.
Include all unaggregated columns in the GROUP BY.
Use LIKE where appropriate.
So, I would suggest:
SELECT a.ssn, a.checktime, p.nama
FROM hki_kepegawaian.fo_absensi a LEFT JOIN
hki_kepegawaian.fo_pegawai b
ON a.ssn = p.nip
WHERE MONTH(checktime) = 8 AND
CAST(a.checktime as TIME) >= '07:30:00' AND
CAST(a.checktime as TIME)) <= '10:00:00' AND
golongan NOT LIKE 'IV%'
GROUP BY a.ssn, p.nama;
Look into count() function.
I can't check whether it works, but try the following query:
SELECT a.ssn, a.checktime, b.nama, count(*) as total
FROM hki_kepegawaian.fo_absensi a
left join hki_kepegawaian.fo_pegawai b on a.ssn = b.nip
where (substring(cast(checktime as DATE), 6, 2) = '08')
and (cast(a.checktime as TIME)) >= '07:30:00' and (cast(a.checktime as
TIME)) <= '10:00:00'
and (substring(golongan, 1, 2)) NOT IN ('IV')
group by ssn, nama
Having total>=1

How to sort before using STUFF in SSRS

I have 2 different values I'm trying to STUFF here. It is Quantity + Price. For example: 1-$0.36; 100-$0.29; 25-$0.31. How can I have it sort by Quantity before being stuffed? (1,25,100 instead of 1,100,25) I did come across this link Sort data before concatenating using STUFF FOR XML, but it dealt with 1 value and I'm dealing with 2 values
SELECT STUFF(
(SELECT DISTINCT TOP (5)
'; ' + (CAST(FLOOR(CASE WHEN PCFBD.Quantity IS NOT NULL THEN PCFBD.Quantity ELSE 1 END) AS VARCHAR) + '-$' + CAST(REPLACE(REPLACE(RTRIM(REPLACE(
CASE WHEN PCF.PriceMethod = 0 THEN ROUND(I.CdCost / (100 - PCF.FormulaPercent) * 100, 2)
WHEN PCFBH.PriceFormula = 2 AND PCFBD.FormulaPercent IS NULL THEN ROUND(I.CdCost / (100 - PCF.FormulaPercent) * 100, 2)
WHEN PCFBH.PriceFormula = 2 AND PCFBD.FormulaPercent IS NOT NULL THEN ROUND(I.CdCost / (100 - PCFBD.FormulaPercent) * 100, 2)
WHEN PCFBH.PriceFormula = 1 THEN ROUND((I.ListPrice * (100 - PCFBD.FormulaPercent)) * .01,2)
ELSE NULL END, '000' ,'')), ' ','0') + '', '. ', '') AS VARCHAR))
FROM Item AS I
INNER JOIN PriceContractFamily AS PCF ON I.FamilyId = PCF.FamilyId
AND I.ItemStatus IN (0, 5)
INNER JOIN StockItem SI ON I.ItemId = SI.ItemId
AND SI.WarehouseId = '502E5876-C26B-4E11-8B88-AFE0C34ECF0D'
LEFT OUTER JOIN PriceContractFamilyBracketHeader AS PCFBH ON PCF.PriceContractFamilyId = PCFBH.PriceContractFamilyId
LEFT OUTER JOIN PriceContractFamilyBracketDetail AS PCFBD ON PCFBH.BracketHeaderId = PCFBD.BracketHeaderId
WHERE I.ListPrice = #ListPrice
AND LEFT(I.ItemNumber, 6) = #ItemNumber
AND PCF.PriceContractId = #PriceContractId
FOR XML PATH('')),1, 2, '') AS QtyPrice
You should be able to add an ORDER BY before the FOR XML PATH statement.

mysql average of best three

I have pieced this together from sites online and it works but not completely, what i need it to do is take the top 3 results and average them but it takes ALL results, can anyone point me in the right direction?
SELECT i.NAME,
e.comp,
Round(Avg(c.phase1 + c.phase2 + c.phase3 + c.phase4 + c.phase5
+ c.phase6), 2) AS "Average Score",
( CASE
WHEN compID = '7' THEN Concat(Round(Avg(
( (
c.phase1 + c.phase2 + c.phase3 + c.phase4 + c.phase5
+ c.phase6 ) / 400 ) * 100), 2), ' %')
WHEN compID = '5' THEN Concat(Round(Avg(
( (
c.phase1 + c.phase2 + c.phase3 + c.phase4 + c.phase5
+ c.phase6 ) / 600 ) * 100), 2), ' %')
WHEN compID = '3' THEN
Concat(Round(Avg(( ( c.phase1 + c.phase2 + c.phase3 + c.phase4 + c.phase5
+ c.phase6 ) / 600 ) * 100), 2), ' %')
ELSE 'Unspecified'
END ) AS "Average as Percent"
FROM jos_practicedetail c,
jos_comps e,
jos_practice g,
jos_members i
WHERE e.compsid = g.competition
AND g.practiceid = c.practicepid
AND i.memberid = c.competitorid
AND g.typeID = '2'
AND Year(g.pdate) = '2017'
AND (SELECT Count(*)
FROM jos_practicedetail b
WHERE b.competitorid = c.competitorid
AND b.practicepid = c.practicepid
AND ( b.phase1 + b.phase2 + b.phase3 + b.phase4 + b.phase5
+ b.phase6 ) >= (
c.phase1 + c.phase2 + c.phase3 + c.phase4 + c.phase5
+ c.phase6 )) <= 3
GROUP BY competitorid
HAVING Count(*) > 2
ORDER BY competitorid,
( Avg(c.phase1 + c.phase2 + c.phase3 + c.phase4 + c.phase5
+ c.phase6) ) DESC

How to sum all titles even others are empty

my query objective is to sum all the fields from (3) tables but i have some problem in generating the final_total_sum output if some of the other titles empty the final_total_sum is empty....but if all titles are not empty my query generate final_total_sum(output).
I wan to do is even other titles are empty my query can still generate a final_total_sum(output).
http://s38.photobucket.com/user/eloginko/media/output_zpsfcab9d54.png.html
current query:
SELECT *,
ROUND(interview_sum +
other_sum +
edu_attain2_sum +
experience2_sum +
trainings2_sum +
eligibility2_sum) AS final_total_sum
FROM (
SELECT
ROUND((SELECT SUM(t2.inttotal)
FROM app_interview2 AS t2
WHERE t2.atic = t.atic)/7,1)
AS interview_sum,
ROUND((SELECT SUM(o2.ototal)
FROM other_app2 AS o2
WHERE o2.oaic = t.atic)/7,1)
AS other_sum,
ROUND((SELECT SUM(s1.edu_attain2)
FROM qual_stan2 AS s1
WHERE s1.oaic2 = t.atic)/7,1)
AS edu_attain2_sum,
ROUND((SELECT SUM(s2.experience2)
FROM qual_stan2 AS s2
WHERE s2.oaic2 = t.atic)/7,1)
AS experience2_sum,
ROUND((SELECT SUM(s3.trainings2)
FROM qual_stan2 AS s3
WHERE s3.oaic2 = t.atic)/7,1)
AS trainings2_sum,
ROUND((SELECT SUM(s4.eligibility2)
FROM qual_stan2 AS s4
WHERE s4.oaic2 = t.atic)/7,1)
AS eligibility2_sum,
t.atid,
t.atic,
t.atname,
t.region,
t.town,
t.uniq_id,
t.position,
t.salary_grade,
t.salary
FROM app_interview2 AS t
WHERE uniq_id = '$q'
GROUP BY t.atname
HAVING COUNT(DISTINCT t.atic)) subq
Try:
ROUND( ifnull(interview_sum,0) +
ifnull(other_sum,0) +
ifnull(edu_attain2_sum,0) +
ifnull(experience2_sum,0) +
ifnull(trainings2_sum,0) +
ifnull(eligibility2_sum,0)) AS final_total_sum
In SQL x + NULL always gives NULL, ifnull function converts nulls to 0
use like SUM(ifnull(t2.inttotal,0))

Mysql Rollup repeatingid field

I have the following query result using group by with rollup:
Divison Department Section Employee Name Employee ID Hours
Assets Asset Strategy Not Defined Monty Mouse 480193 64.00
Assets Asset Strategy Not Defined Frank Flint 480165 67.50
Assets Asset Strategy Not Defined 480165 131.50
Assets Asset Strategy 480165 131.50
Assets Event Centre Not Defined Sally Spoons 800192 72.00
Assets Event Centre Not Defined Randolph Smith 800199 37.50
Assets Event Centre Not Defined Petra Peters 800195 64.00
Assets Event Centre Not Defined 800195 173.50
Assets Event Centre 800195 173.50
What I want to be able to do is to stop the employee id from replicating in the rollup lines:
Divison Department Section Employee Name Employee ID Hours
Assets Asset Strategy Not Defined Monty Mouse 480193 64.00
Assets Asset Strategy Not Defined Frank Flint 480165 67.50
Assets Asset Strategy Not Defined 131.50
Assets Asset Strategy 131.50
Assets Event Centre Not Defined Sally Spoons 800192 72.00
Assets Event Centre Not Defined Randolph Smith 800199 37.50
Assets Event Centre Not Defined Petra Peters 800195 64.00
Assets Event Centre Not Defined 173.50
Assets Event Centre 173.50
I've read other posts about using union to try to just match up the employee if from a non-rollup query, but this hasn't worked for me.
I've also read about using sub-select (wrapping) to get the employee id, but this has just lead to the same result.
My rollup statement groups by division, department, section and employee name. If I try to add employee id to this clause I get a rollup on every change of employee. I've also changed the order of the name and if fields and tried grouping by the id rather than the name, but this has just replicated the name in the same way the id is above.
Am I chasing the impossible dream here? Is it not actually possible to display the data in this way? Any suggestions would be greatly appreciated.
For those that would like the full query code, here it is:
select distinct
hr_func_desc('CD_DEPT_', p.department) as 'Department',
hr_func_desc('CD_DIVN_', p.division) as 'Division',
hr_func_desc('CD_SECT_', p.section) as 'Section',
pe.payroll_name as 'Employee Name',
pe.employee_id as 'Employee ID',
max(e.termination_date) as 'Termination Date',
sum(ph.ordinary_hours) as 'Ordinary Hours',
sum(ph.overtime_1_hours) as 'Overtime 1 Hours',
sum(ph.overtime_2_hours) as 'Overtime 2 Hours',
sum(ph.overtime_1_hours) + sum(ph.overtime_2_hours) as 'Total Overtime Hours',
sum(ph.ordinary_hours) + sum(ph.overtime_1_hours) + sum(ph.overtime_2_hours) as 'Total Hours Worked',
sum(al.units) as 'Number of Standby Worked',
sum(ph.statutory_hours) as 'Statutory Holidays',
sum(ph.annual_leave_hours) as 'Annual Leave',
sum(ph.long_service_leave_hours) as 'Long Service Leave',
sum(ph.special_leave_hours) as 'Special Leave',
sum(ph.time_in_alt_hours) as 'Alt Lieu',
sum(ph.parental_leave_hours) as 'Parental Leave',
sum(ph.sick_hours) as 'Sick',
sum(ph.domestic_leave_hours) as 'Domestic',
sum(ph.bereavement_hours) as 'Bereavement',
sum(ph.acc_week_1_hours) as 'ACC Week 1',
sum(ph.acc_hours) as 'ACC Unpaid',
sum(ph.lwop_hours) as 'Leave Without Pay',
sum(ph.sick_hours) + sum(ph.domestic_leave_hours) + sum(ph.bereavement_hours) + sum(ph.annual_leave_hours) + sum(ph.statutory_hours) +
sum(ph.special_leave_hours) + sum(ph.long_service_leave_hours) + sum(ph.time_in_lieu_hours) + sum(ph.time_in_alt_hours) + sum(ph.lwop_hours) +
sum(ph.standby_leave_hours) + sum(ph.parental_leave_hours) + sum(ph.acc_week_1_hours) + sum(ph.acc_hours) as 'Total Hours Absent',
sum(ph.ordinary_hours) + sum(ph.overtime_1_hours) + sum(ph.overtime_2_hours) + sum(ph.statutory_hours) + sum(ph.annual_leave_hours) +
sum(ph.long_service_leave_hours) + sum(ph.special_leave_hours) + sum(ph.time_in_alt_hours) + sum(ph.sick_hours) + sum(ph.domestic_leave_hours) +
sum(ph.bereavement_hours) + sum(ph.acc_week_1_hours) as 'Total Hours Paid',
hr_func_normal_hours(pe.employee_id) as 'Normal Hours Worked per Week',
sum(cast(pt.pay_weeks as unsigned integer)) as 'Pay Weeks for Period Chosen',
round((sum(ph.ordinary_hours) + sum(ph.overtime_1_hours) + sum(ph.overtime_2_hours) + sum(ph.sick_hours) + sum(ph.domestic_leave_hours) +
sum(ph.bereavement_hours) + sum(ph.statutory_hours) + sum(ph.special_leave_hours) + sum(ph.time_in_lieu_hours) + sum(ph.time_in_alt_hours) +
sum(ph.lwop_hours) + sum(ph.acc_week_1_hours) + sum(ph.acc_hours) + sum(ph.standby_leave_hours) + sum(ph.parental_leave_hours))
/sum(cast(pt.pay_weeks as unsigned integer)), 2) as 'Calculated FTE Hours',
truncate(((sum(ph.ordinary_hours) + sum(ph.overtime_1_hours) + sum(ph.overtime_2_hours) + sum(ph.sick_hours) + sum(ph.domestic_leave_hours) +
sum(ph.bereavement_hours) + sum(ph.statutory_hours) + sum(ph.special_leave_hours) + sum(ph.time_in_lieu_hours) + sum(ph.time_in_alt_hours) +
sum(ph.lwop_hours) + sum(ph.acc_week_1_hours) + sum(ph.acc_hours) + sum(ph.standby_leave_hours) + sum(ph.parental_leave_hours))
/sum(cast(pt.pay_weeks as unsigned integer)))/hr_func_normal_hours(pe.employee_id), 3) as 'Calculated FTE'
from swpayroll.py_employees pe
left outer join swhr_rails.hr_employees e on e.id = pe.employee_id
left outer join swhr_rails.hr_employee_positions ep on pe.employee_id = ep.employee_id
left outer join swhr_rails.hr_positions p on ep.position_id = p.id
left outer join swpayroll.py_rep_hist_hours ph on pe.employee_id = ph.employee_id
left outer join swpayroll.py_hist_dedns_allowances al
on al.employee_id = pe.employee_id
and al.pay_date = ph.pay_date
and al.da_id in (33, 66, 67)
left outer join swpayroll.py_hist_totals pt on pt.employee_id = pe.employee_id and pt.pay_date = ph.pay_date
where ep.position_id = (select min(x.position_id) from swhr_rails.hr_employee_positions as x
where x.employee_id = pe.employee_id and x.position_end is null)
and ph.pay_date between '2012-10-21' and '2012-11-04'
group by
hr_func_desc('CD_DEPT_', p.department),
hr_func_desc('CD_DIVN_', p.division),
hr_func_desc('CD_SECT_', p.section),
pe.payroll_name with rollup;
Smaller snippit of code:
select distinct
hr_func_desc('CD_DEPT_', p.department) as 'Department',
hr_func_desc('CD_DIVN_', p.division) as 'Division',
hr_func_desc('CD_SECT_', p.section) as 'Section',
pe.payroll_name as 'Employee Name',
pe.employee_id as 'Employee ID',
sum(ph.ordinary_hours) as 'Ordinary Hours'
from swpayroll.py_employees pe
left outer join swhr_rails.hr_employees e on e.id = pe.employee_id
left outer join swhr_rails.hr_employee_positions ep on pe.employee_id = ep.employee_id
left outer join swhr_rails.hr_positions p on ep.position_id = p.id
left outer join swpayroll.py_rep_hist_hours ph on pe.employee_id = ph.employee_id
left outer join swpayroll.py_hist_dedns_allowances al
on al.employee_id = pe.employee_id
and al.pay_date = ph.pay_date
and al.da_id in (33, 66, 67)
left outer join swpayroll.py_hist_totals pt on pt.employee_id = pe.employee_id and pt.pay_date = ph.pay_date
where ep.position_id = (select min(x.position_id) from swhr_rails.hr_employee_positions as x
where x.employee_id = pe.employee_id and x.position_end is null)
and ph.pay_date between '2012-10-21' and '2012-11-04'
group by
hr_func_desc('CD_DEPT_', p.department),
hr_func_desc('CD_DIVN_', p.division),
hr_func_desc('CD_SECT_', p.section),
pe.payroll_name with rollup;
From what I understand, having posted the same question in the mysql.com forums (http://forums.mysql.com/read.php?10,577674,577674#msg-577674), there is no way to eliminate this repetition at query time.
It would need to be done programatically via a secondary procedural language.