Multiple JOINS using UNION ALL with WHERE clause - php

I wanted to generate a report. User have to select position name using dropdown menu. This the the query that I've wrote but it's not working and I don't how else need to fix. Any helps appreciated.
SELECT * FROM
(
SELECT COUNT(tapplied.applied_id) as TotalCandidate, exam_code.exam_name
FROM ((exam
INNER JOIN tapplied ON exam.applied_id = tapplied.applied_id)
INNER JOIN exam_code ON exam.exam_id = exam_code.exam_id)
WHERE exam_code.exam_id <> '8'
GROUP BY exam_name
UNION ALL
SELECT COUNT(tapplied.exam_id) as TotalCandidate, level_code.level_name
FROM ((tipt INNER JOIN tapplied ON tipt.applied_id = tapplied.applied_id)
INNER JOIN level_code ON tipt.level_id = level_code.level_id)
GROUP BY level_name
) x
WHERE x.position_name = '{$jaw}'

Related

How can I perform a calculation in mysql with result variables, did try sum () but does not work here

I can't figure out how to do the calculation, i know how to calculate it on the result in php. but i am sure there must be a way to do it in the query.
i need the projectTotal and the opdrachtTotal in the result
SELECT
TABLE_PROJECTEN.id,
TABLE_PROJECTEN.code as pCode,
TABLE_OPDRACHTEN.code as oCode,
(SELECT COALESCE(SUM(t_kosten.aantal * t_kosten.bedrag),0) FROM `t_kosten` WHERE t_kosten.id_ref_project = TABLE_PROJECTEN.id) AS projectKosten,
(SELECT COALESCE(SUM(t_opbrengsten.aantal * t_opbrengsten.bedrag),0) FROM `t_opbrengsten` WHERE t_opbrengsten.id_ref_project = TABLE_PROJECTEN.id) AS projectOpbrengsten,
(SELECT COALESCE(SUM(t_kosten.aantal * t_kosten.bedrag),0) FROM `t_kosten` WHERE t_kosten.id_ref_opdracht =TABLE_OPDRACHTEN.id) AS opdrachtKosten
(SELECT COALESCE(SUM(t_opbrengsten.aantal * t_opbrengsten.bedrag),0) FROM `t_opbrengsten` WHERE t_opbrengsten.id_ref_opdracht =TABLE_OPDRACHTEN.id) AS opdrachtOpbrengsten,
(CALCULATE HERE: projectOpbrengsten-projectKosten) as projectTotal,
(CALCULATE HERE: opdrachtOpbrengsten-opdrachtKosten) as opdrachtTotal
FROM
t_project TABLE_PROJECTEN
LEFT JOIN t_opdracht TABLE_OPDRACHTEN on TABLE_OPDRACHTEN.id_ref_project = TABLE_PROJECTEN.id
GROUP BY TABLE_OPDRACHTEN.code
You can perform your calculations in individual sub clauses and join with your main query instead of dependent sub queries. Doing this way you can reuse the results of sub clauses tog get your totals.
SELECT
p.id,
p.code AS pCode,
o.code AS oCode,
COALESCE(tk1.projectKosten,0) AS projectKosten,
COALESCE(to1.projectOpbrengsten,0) AS projectOpbrengsten,
COALESCE(tk2.opdrachtKosten,0) AS opdrachtKosten
COALESCE(to2.opdrachtOpbrengsten,0) AS opdrachtOpbrengsten,
(COALESCE(to1.projectOpbrengsten,0) - COALESCE(tk1.projectKosten,0)) AS projectTotal,
(COALESCE(to2.opdrachtOpbrengsten,0) - COALESCE(tk2.opdrachtKosten,0) ) AS opdrachtTotal
FROM t_project p
LEFT JOIN t_opdracht o ON o.id_ref_project = p.id projectKosten
LEFT JOIN (
SELECT id_ref_project COALESCE(SUM(aantal * bedrag),0)
FROM `t_kosten`
GROUP id_ref_project
) tk1 ON tk1.id_ref_project = p.id
LEFT JOIN (
SELECT id_ref_project, SUM(aantal * bedrag) projectOpbrengsten
FROM `t_opbrengsten`
GROUP BY id_ref_project
) to1 ON to1.id_ref_project = p.id
LEFT JOIN (
SELECT id_ref_opdracht ,SUM(t_kosten.aantal * t_kosten.bedrag) opdrachtKosten
FROM `t_kosten`
GROUP BY id_ref_opdracht
) tk2 ON tk2.id_ref_opdracht =o.id
LEFT JOIN (
SELECT id_ref_opdracht,SUM(aantal * bedrag) AS opdrachtOpbrengsten
FROM `t_opbrengsten`
GROUP BY id_ref_opdracht
) to2 ON to2.id_ref_opdracht =o.id
Also i don't see the purpose of doing group by on TABLE_OPDRACHTEN.code

Merge two MySQL queries working fine separately

SELECT sum(monthly_target) as month_target
FROM `tbl_goal`
inner join user
on tbl_goal.uid=user.id where user.store=1 and month='February'
result: month_target = 9000
SELECT
sum(net) as achieved,
sum(hairs_total) as hairs_total,
sum(beard_total) as beard_total,
sum(product_total) as product_total
FROM `data`
inner join user
on data.uid=user.id where user.store=1 and month='February'
result: achieved =103 hairs_total =63 beard_total = 40 product_total = 0
please give me any hint how can join these into one?
Tricky one. Your current join condition implies that you want to aggregate by user, but the WHERE clause makes it clear that you want store-level aggregates. So, we can try rewriting your query to aggregate by store. Each of the two subqueries below performs separate aggregations, bringing in the store id via a join to the user table. Then, on the outside we join the user table to each of these subqueries.
SELECT
u.store,
COALESCE(t1.achieved, 0) AS achieved,
COALESCE(t1.hairs_total, 0) AS hairs_total,
COALESCE(t1.beard_total, 0) AS beard_total,
COALESCE(t1.product_total, 0) AS product_total,
COALESCE(t2.month_target 0) AS month_target
FROM user u
LEFT JOIN
(
SELECT
usr.store,
SUM(d.net) AS achieved,
SUM(d.hairs_total) AS hairs_total,
SUM(d.beard_total) AS beard_total,
SUM(d.product_total) AS product_total
FROM data d
INNER JOIN user usr
ON d.uid = usr.id
WHERE d.month = 'February'
GROUP BY usr.store
) t1
ON u.store = t1.store
LEFT JOIN
(
SELECT
usr.store,
SUM(t.monthly_target) AS month_target
FROM tbl_goal t
INNER JOIN user usr
ON t.uid = usr.id
WHERE t.month = 'February'
GROUP BY usr.store
) t2
ON u.store = t2.store;
WHERE
u.store = 1;
If you wanted a report of all stores, just remove the outer WHERE clause.
Use multiple inner join to achieve this .
Try this
SELECT sum(tbl_goal.monthly_target) as month_target, sum(data.net) as achieved,
sum(data.hairs_total) as hairs_total,
sum(data.beard_total) as beard_total,
sum(data.product_total) as product_total
FROM `tbl_goal`
inner join user
on tbl_goal.uid=user.id
inner join data on tbl_goal.uid=data.uid
where user.store=1 and data.month='February'
SELECT
sum(monthly_target) as month_target,
sum(net) as achieved,
sum(hairs_total) as hairs_total,
sum(beard_total) as beard_total,
sum(product_total) as product_total
FROM
user
inner join `tbl_goal` on tbl_goal.uid = user.id
inner join `data` on data.uid = user.id
where
user.store = 1
and month = 'February'

Loading details from multiple tables

I was using this:
SELECT res.*, rac.*, u.*, t.*, c.*
FROM Results res
INNER JOIN Races rac USING (RaceID)
INNER JOIN Users u USING (UserID)
INNER JOIN Teams t USING (TeamID)
INNER JOIN Cars c USING (CarID)
WHERE res.SeasonNumber = '$SeasonNumber' AND res.LeagueID = '$LeagueID' AND Position = '1' AND ResultConfirmed = '1'
ORDER BY Position ASC
Which works fine, but I've since realised I need to have CarID added in to Results table, but when I add it in, it gives me the error that the field is ambiguous. What I'd like to do is get the Car name from Cars table where CarID joins Cars and Results. When I try to do this though:
SELECT res.*, rac.*, u.*, t.*, c.*
FROM Results res
INNER JOIN Races rac USING (RaceID)
INNER JOIN Users u USING (UserID)
INNER JOIN Teams t USING (TeamID)
INNER JOIN Cars c USING (res.CarID)
WHERE res.SeasonNumber = '$SeasonNumber' AND res.LeagueID = '$LeagueID' AND Position = '1' AND ResultConfirmed = '1'
ORDER BY Position ASC
I get the following error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '.CarID) WHERE res.SeasonNumber = '1' AND res.LeagueID = '1' AND
Position = '1' ' at line 6
You can replace your USING clause with ON(),in USING() clause i guess you add the columns name that are same in other table you are joining but you placed the join in last and using alias res mysql won't allow this
INNER JOIN Cars c ON(res.CarID =c.CarID)
If you need to use USING() clause you need to adjust the join placements like
SELECT res.*, rac.*, u.*, t.*, c.*
FROM
Cars c
INNER JOIN Results res USING (CarID)
INNER JOIN Races rac USING (RaceID)
INNER JOIN Users u USING (UserID)
INNER JOIN Teams t USING (TeamID)
WHERE res.SeasonNumber = '$SeasonNumber' AND res.LeagueID = '$LeagueID' AND Position = '1' AND ResultConfirmed = '1'
ORDER BY Position ASC
But ON() clause is more readable form

MySQL Query left join repeated records

With a Left Join i have this result.
Here the screen
http://f.cl.ly/items/373Y141r1K131d0n3f1q/Schermata%202013-04-01%20alle%2016.51.18.png
i want to show only record once time, without repeat it, but with a left join all my records are different.
what i have to do for show once all my records?
the query.
SELECT * FROM login_users
LEFT JOIN login_users_seguaci
ON login_users.user_id = login_users_seguaci.following
WHERE name LIKE ""
AND user_id != '1'
ORDER BY data DESC
SELECT x.*, y.*
FROM login_users x
LEFT JOIN
(
SELECT a.*
FROM login_users_seguaci a
INNER JOIN
(
SELECT following, MAX(DATA) max_data
FROM login_users_seguaci
GROUP BY following
) b ON a.following = b.following AND
a.DATA = b.max_date
) y ON x.user_id = y.following
// WHERE ... your condition here ...
ORDER BY t.data DESC

Limiting a left join to returning one result?

I currently have this left join as part of a query:
LEFT JOIN movies t3 ON t1.movie_id = t3.movie_id AND t3.popularity = 0
The trouble is that if there are several movies with the same name and same popularity (don't ask, it just is that way :-) ) then duplicate results are returned.
All that to say, I would like to limit the result of the left join to one.
I tried this:
LEFT JOIN
(SELECT t3.movie_name FROM movies t3 WHERE t3.popularity = 0 LIMIT 1)
ON t1.movie_id = t3.movie_id AND t3.popularity = 0
The second query dies with the error:
Every derived table must have its own alias
I know what I'm asking is slightly vague since I'm not providing the full query, but is what I'm asking generally possible?
The error is clear -- you just need to create an alias for the subquery following its closing ) and use it in your ON clause since every table, derived or real, must have its own identifier. Then, you'll need to include movie_id in the subquery's select list to be able to join on it. Since the subquery already includes WHERE popularity = 0, you don't need to include it in the join's ON clause.
LEFT JOIN (
SELECT
movie_id,
movie_name
FROM movies
WHERE popularity = 0
ORDER BY movie_name
LIMIT 1
) the_alias ON t1.movie_id = the_alias.movie_id
If you are using one of these columns in the outer SELECT, reference it via the_alias.movie_name for example.
Update after understanding the requirement better:
To get one per group to join against, you can use an aggregate MAX() or MIN() on the movie_id and group it in the subquery. No subquery LIMIT is then necessary -- you'll receive the first movie_id per name withMIN() or the last with MAX().
LEFT JOIN (
SELECT
movie_name,
MIN(movie_id) AS movie_id
FROM movies
WHERE popularity = 0
GROUP BY movie_name
) the_alias ON t1.movie_id = the_alias.movie_id
LEFT JOIN movies as m ON m.id = (
SELECT id FROM movies mm WHERE mm.movie_id = t1.movie_id
ORDER BY mm.id DESC
LIMIT 1
)
you could try to add GROUP BY t3.movie_id to the first query
Try this:
LEFT JOIN
(
SELECT t3.movie_name, t3.popularity
FROM movies t3 WHERE t3.popularity = 0 LIMIT 1
) XX
ON t1.movie_id = XX.movie_id AND XX.popularity = 0
On MySQL 5.7+ use ANY_VALUE & GROUP_BY:
SELECT t1.id,t1.movie_name, ANY_VALUE(t3.popularity) popularity
FROM t1
LEFT JOIN t3 ON (t3.movie_id=t1.movie_id AND t3.popularity=0)
GROUP BY t1.id
more info
LEFT JOIN only first row
https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
Easy solution to left join the 1 most/least recent row is using select over ON phrase
SELECT A.ID, A.Name, B.Content
FROM A
LEFT JOIN B
ON A.id = (SELECT MAX(id) FROM B WHERE id = A.id)
Where A.id is the auto-incremental primary key.
LEFT JOIN (
SELECT id,movie_name FROM movies GROUP BY id
) as m ON (
m.id = x.id
)
// Mysql
SELECT SUM(db.item_sales_nsv) as total FROM app_product_hqsales_otc as db
LEFT JOIN app_item_target_otc as it ON
db.id = (SELECT MAX(id) FROM app_item_target_otc as ot WHERE id = db.id)
and db.head_quarter = it.hqcode
AND db.aaina_item_code = it.aaina_item_code AND db.month = it.month
AND db.year = it.year
WHERE db.head_quarter = 'WIN001' AND db.month = '5' AND db.year = '2022' AND db.status = '1'

Categories