MySql calculate multiple column - mysql

I have code below and in my query but the results it gives me is way off chart, so I thought maybe my calculation is wrong. The Logic is to have multiple column sum minus and times to eachother and the result based on my database numbers has to be 4.581.709.50 but I get something like 164.610.000
SUM(c.gaji_pokok + c.uang_makan + c.tunjangan + c.kendaraan + c.overtime + c.komisi + c.lain_lain + c.cuti -
m.pot_absen_hari * m.pot_absen_rate - IFNULL(g.pot_absen_hari * g.pot_absen_rate, 0) - CONCAT((c.uang_makan)/0.25)*0.05 -
n.pot_komisi_dl - n.pot_komisi_p312 - n.pot_komisi_mteg - IFNULL(g.pot_komisi_kasbon, 0) - q.bpjs4 - o.pot_ppn_21pt - o.pot_pinjaman - o.pot_ppn21 - o.pot_bayar_bonus -
o.pot_bayar_thr - c.cuti) as bulan_ppn21,
Query
SELECT
a.nip,
SUM(c.gaji_pokok + c.uang_makan + c.tunjangan + c.kendaraan + c.overtime + c.komisi + c.lain_lain + c.cuti -
m.pot_absen_hari * m.pot_absen_rate - IFNULL(g.pot_absen_hari * g.pot_absen_rate, 0) - CONCAT((c.uang_makan)/0.25)*0.05 -
n.pot_komisi_dl - n.pot_komisi_p312 - n.pot_komisi_mteg - IFNULL(g.pot_komisi_kasbon, 0) - q.bpjs4 - o.pot_ppn_21pt - o.pot_pinjaman - o.pot_ppn21 - o.pot_bayar_bonus -
o.pot_bayar_thr - c.cuti) as bulan_ppn21,
IFNULL((
CASE
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=50000000)
THEN (0.05*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)))
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=250000000)
THEN (0.15*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.15)-(q.jht*12)))
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=500000000)
THEN (0.25*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.25)-(q.jht*12))) end),0) as tahun_pph21,
IFNULL((
CASE
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=50000000)
THEN (0.05*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)))
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=250000000)
THEN (0.15*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.15)-(q.jht*12)))
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=500000000)
THEN (0.25*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.25)-(q.jht*12))) end) -(
CASE
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=50000000)
THEN (0.05*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)))
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=250000000)
THEN (0.15*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.15)-(q.jht*12)))
WHEN ((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)<=500000000)
THEN (0.25*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.25)-(q.jht*12))) end)/12,0) - (
CASE
WHEN (((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate))<=50000000)
THEN (0.05*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate)))
WHEN (((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate))<=250000000)
THEN (0.15*((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate))-5000000)
WHEN (((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate))<=500000000)
THEN (0.25*(0.03*(c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate))-55000000)*1.2
WHEN (((c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate))<=500000000)
THEN (0.25*(0.03*(c.gaji_pokok * 12)-((c.gaji_pokok * 12)*0.05)-(q.jht*12)-(r.pt_kp_rate))-55000000)*1.2 end) as tot_pph21
FROM `t_pegawai` a
LEFT JOIN t_penggajian_karyawan c ON c.nip=a.nip
LEFT JOIN t_departemen d ON d.id_departemen=a.id_departemen
LEFT JOIN t_jabatan e ON e.id_jabatan=a.id_jabatan
LEFT JOIN t_perusahaan f ON f.kode_unitbisnis = a.unit_bisnis
LEFT JOIN absensi k ON k.pin = a.pin
LEFT JOIN t_periode l ON l.nama_periode=c.bulan and YEAR(l.periode_start) = c.tahun
LEFT JOIN t_potongan_absen m ON m.nip=a.nip and m.nip=c.nip and m.bulan = l.id_periode and m.tahun = YEAR(l.periode_start)
LEFT JOIN t_potongan_gaji g ON g.nip=a.nip and g.nip=c.nip and g.bulan = l.id_periode and g.tahun = YEAR(l.periode_start)
LEFT JOIN t_potongan_komisi n ON n.nip=a.nip and n.nip=c.nip and n.bulan = l.id_periode and n.tahun = YEAR(l.periode_start)
LEFT JOIN t_potongan_ppn o ON o.nip=a.nip and o.nip=c.nip and o.bulan = l.id_periode and o.tahun = YEAR(l.periode_start)
LEFT JOIN t_jenjang_bpjs q ON q.nip=a.nip and q.tahun = YEAR(l.periode_start)
LEFT JOIN t_ptkp r ON r.pt_kp_name=a.status_ptkp
WHERE l.id_periode='8' AND f.kode_unitbisnis ='PJS-001' and k.Tanggal >= l.periode_start and k.Tanggal <= l.periode_end
GROUP BY a.pin
Any suggestion on calculation way to make it right?

Related

Reusing calculations in an SQL query

Is it possible to simplify this sql query? Lots of calculations are reused and it would be nice to name each expression and use the name instead of the full expression.
SELECT SUM(T2.price * T1.amount) As price,
(SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100))) As base_price,
((SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100))) * (T3.vat / 100)) As vat_amount,
(((SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100))) * (T3.vat / 100)) + (SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100)))) As total_price
I'm looking for a solution similar to this:
SELECT SUM(T2.price * T1.amount) As price,
(price - (price * (T3.discount / 100))) As base_price,
(base_price) * (T3.vat / 100)) As vat_amount,
(vat_amount) + (base_price) As total_price
I tried doing it with CTE's and subqueries as suggested but it ended up looking pretty complicated and undreadable so I decided to just do the calculations outside of sql (php in this case)
Maybe something like that:
select
(A.price - (A.price * B.p_discount)) As base_price,
((A.price - (A.price * B.p_discount)) * B.p_vat) As vat_amount,
(((A.price - (A.price * B.p_discount)) * B.p_vat) + (A.price - (A.price * B.p_discount))) As total_price
from
( select SUM(T2.price * T1.amount) As price, ...
from T1 join T2 on ....
) A
join
(select (T3.discount / 100) as p_discount , (T3.vat / 100) as p_vat ,*
from T3
) B on ...

How can I do an inner join inside of a subquery? MySQL

I am trying to adapt this select statement to my tables. This query selects all of the zip codes from a zip code table that are within a certain distance of a given zip code. However, I have a Salon table that stores the zip codes as a foreign from the zip code table. I need to select all of the salons within a certain distance of the given zip code.
DELIMITER //
CREATE PROCEDURE zip_search(lat_param FLOAT(9,6),
long_param FLOAT(9,6), dist_param INT(100)
)
BEGIN
SELECT zipcode
FROM (
SELECT z.zipcode, z.latitude, z.longitude,
p.radius,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(z.latitude))
* COS(RADIANS(p.longpoint - z.longitude))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(z.latitude)))) AS distance
FROM accounts_zip AS z
JOIN ( /* these are the query parameters */
SELECT lat_param AS latpoint, long_param AS longpoint,
dist_param AS radius, 69.0 AS distance_unit
) AS p ON 1=1
WHERE z.latitude
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND z.longitude
BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
) AS d
WHERE distance <= radius
ORDER BY distance;
END //
I tried adding an inner join after selecting from the salon table, however I do not understand sub queries and joins very well. Any thoughts would be greatly appreciated.
DELIMITER //
CREATE PROCEDURE zip_search(lat_param FLOAT(9,6),
long_param FLOAT(9,6), dist_param INT(100)
)
BEGIN
SELECT *
FROM (
SELECT z.zipcode, z.latitude, z.longitude,
p.radius,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(z.latitude))
* COS(RADIANS(p.longpoint - z.longitude))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(z.latitude)))) AS distance
FROM accounts_salon INNER JOIN accounts_zip ON accounts_salon.id=accounts_zip.id AS z
JOIN ( /* these are the query parameters */
SELECT lat_param AS latpoint, long_param AS longpoint,
dist_param AS radius, 69.0 AS distance_unit
) AS p ON 1=1
WHERE z.latitude
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND z.longitude
BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
) AS d
WHERE distance <= radius
ORDER BY distance;
END //
I don't think the ' AS z' in first inner join is necessary, if you try to get the join result of tables accounts_salon and accounts_zip, and treat it as the left table of second inner join, then just continure write the next inner join.

How to avoid multiple column in correlated sub query assignment in MySQL update

I'm attempting to assign the closest location to a community based on the community postcode and using the Haversine formula with SQL described here. I need to return a single scalar value but I can't seem to avoid having the second calculated distance value which is needed to determine the closest location. Help.
UPDATE Community AS c
JOIN Postcode p on p.id = c.postcode_id
JOIN (
SELECT 100.0 AS radius, 111.045 AS distance_unit
) AS a
SET c.location_id = (
SELECT l.id,
a.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latitude))
* COS(RADIANS(l.latitude))
* COS(RADIANS(p.longitude - l.longitude))
+ SIN(RADIANS(p.latitude))
* SIN(RADIANS(l.latitude)))) AS distance
FROM Location AS l
WHERE l.latitude
BETWEEN p.latitude - (a.radius / a.distance_unit)
AND p.latitude + (a.radius / a.distance_unit)
AND l.longitude
BETWEEN p.longitude - (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
AND p.longitude + (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
HAVING distance <= a.radius
ORDER BY distance
LIMIT 1
)
Using the structure you have, you need to move the distance calculation into the WHERE and ORDER BY clauses:
SET c.location_id = (
SELECT l.id
FROM Location AS l
WHERE l.latitude
BETWEEN p.latitude - (a.radius / a.distance_unit)
AND p.latitude + (a.radius / a.distance_unit)
AND l.longitude
BETWEEN p.longitude - (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
AND p.longitude + (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
AND a.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latitude))
* COS(RADIANS(l.latitude))
* COS(RADIANS(p.longitude - l.longitude))
+ SIN(RADIANS(p.latitude))
* SIN(RADIANS(l.latitude)))) <= a.radius
ORDER BY a.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latitude))
* COS(RADIANS(l.latitude))
* COS(RADIANS(p.longitude - l.longitude))
+ SIN(RADIANS(p.latitude))
* SIN(RADIANS(l.latitude))))
LIMIT 1
)

MySQL column not found despite being declared?

This query works:
select d.*,
(6371 * 3.1415926 * SQRT((:lat - dl.lat) * (:lat - dl.lat) + COS(:lat / 57.2957795) * COS(dl.lat / 57.2957795) * (:long - dl.long) * (:long - dl.long)) / 180) as xdistance
from `dudes` as d
left join `dude_locations` as dl on (dl.id_dude = d.id)
where
(6371 * 3.1415926 * SQRT((:lat - dl.lat) * (:lat - dl.lat) + COS(:lat / 57.2957795) * COS(dl.lat / 57.2957795) * (:long - dl.long) * (:long - dl.long)) / 180) <= dl.distance
group by d.id
limit 20
However, this query throws a "column xdistance not found" error:
select d.*,
(6371 * 3.1415926 * SQRT((:lat - dl.lat) * (:lat - dl.lat) + COS(:lat / 57.2957795) * COS(dl.lat / 57.2957795) * (:long - dl.long) * (:long - dl.long)) / 180) as xdistance
from `dudes` as d
left join `dude_locations` as dl on (dl.id_dude = d.id)
where
xdistance <= dl.distance
group by d.id
limit 20
All I'm trying to do is make it so the same calculation isn't made twice. Is this possible?
Any help would be appreciated.
where
d.xdistance <= dl.distance
It is possible that the query you want is something like this:
select d.*,
MIN((6371 * 3.1415926 * SQRT((:lat - dl.lat) * (:lat - dl.lat) + COS(:lat / 57.2957795) * COS(dl.lat / 57.2957795) * (:long - dl.long) * (:long - dl.long)) / 180) ) as xdistance
from `dudes` as d left join
`dude_locations` as dl
on (dl.id_dude = d.id)
group by d.id
having xdistance <= min(dl.distance)
limit 20;

MySQL, select rows where a parameter value depends on the value that it has in a different row

I have a table where I can find the same parameter in subsequent rows (See Example A). I need a query to select only the rows where the value is different from the previous row (See Example B), something like
SELECT * FROM tableName WHERE Par(id)!=Par(id-1)
It shouldn't be difficult but I'm new to MySQL (and databases in general) and I haven't found an command or an example for this.
Example A Example B
********* *********
*ID *Par* **ID*Par*
********* *********
*1 * a * *5 * a *
*2 * a * *6 * g *
*3 * a * *7 * f *
*4 * a * *8 * d *
*5 * a * *9 * f *
*6 * g * *10 * h *
*7 * f * *11 * j *
*8 * d * *12 * f *
*9 * f * *17 * f *
*10 * h * *18 * d *
*11 * j * *19 * s *
*12 * f * *20 * g *
*13 * f * *21 * t *
*14 * f * *22 * g *
*15 * f *
*16 * f *
*17 * f *
*18 * d *
*19 * s *
*20 * g *
*21 * t *
*22 * g *
Try this:
SELECT t.id,t.par FROM your_table t
WHERE t.par <>
(SELECT par FROM your_table
WHERE id = t.id + 1)
SELECT DISTINCT Par
FROM table_name
http://www.w3schools.com/sql/sql_distinct.asp