mysql : calculations on alias fields in mysql - mysql

I already referred :
How to use alias as field in mysql
&
Adding MySQL alias fields together
I want to some calculations on alias fields but it throws error
following is my query
select j.*,
(select sum(stars) from ratingstar where jobid=j.id) as stars,
(select count(*) from ratingstar where jobid=j.id) as count,
((stars/(count*5)*5)) as rating //I have problem here if I remove this it works fine
from jobs j inner join proposals p on p.jobid=j.id
inner join us_signup u on u.id=p.userid
inner join hired h on h.proposalid=p.id
where h.status="finished"
But it throws error
error in this select line
select j.*,
(select sum(stars) from ratingstar where jobid=j.id) as stars,
(select count(*) from ratingstar where jobid=j.id) as count,
((stars/(count*5)*5)) as rating //I have problem here if I remove this it works fine
and error is
Fatal error: Uncaught exception 'Exception' with message 'Unknown
column 'stars' in 'field list' query: select j.,(select sum(stars)
from ratingstar where jobid=j.id) as stars,(select count() from
ratingstar where jobid=j.id) as count,((stars/(count*5)*5)) as rating
from jobs j inner join proposals p on p.jobid=j.id inner join
us_signup u on u.id=p.userid inner join hired h on h.proposalid=p.id
where h.status="finished"' in
E:\wamp\www\sugumar\mysuite\includes\classes\MysqliDb.php on line 3637

i think you missed a ) at the end
((stars/(count*5)*5))
edit* you didnt miss it,you just added an useless one at the beginning
(stars/(count*5)*5)

Count is a reserved SQL term, if you want to use is as a field, you should do it like this:
select j.*,
(select sum(stars) from ratingstar where jobid=j.id) as stars,
(select count(*) from ratingstar where jobid=j.id) as count,
((stars/(`count`*5)*5)) as rating //I have problem here if I remove this it works fine
from jobs j inner join proposals p on p.jobid=j.id
inner join us_signup u on u.id=p.userid
inner join hired h on h.proposalid=p.id
where h.status="finished"

Since count is a reserved word/function, you need to quote it using backticks:
select j.*,
(select sum(`stars`) from `ratingstar` where `jobid` = j.`id`) as `stars`,
(select count(*) from `ratingstar` where `jobid` = j.`id`) as `count`,
(`stars` / (`count` * 5) * 5) as `rating`
from `jobs` j
inner join `proposals` p
on p.`jobid` = j.`id`
inner join `us_signup` u
on u.`id` = p.`userid`
inner join `hired` h
on h.`proposalid` = p.`id`
where h.`status` = "finished"

Related

Two Select statements into one

I'm using MySql 8.0.23 and have two select statements. The first one reads like this:
SELECT w.userid,w.reportdate, t.teamname, sum(w.worked)/60 as Worked FROM apticproject.view_workedtime as w
inner join user u on u.userid=w.userid
left outer join teammembers m on m.member=w.userid
left outer join teams t on t.teamid=m.team
where reportdate >= '2021-03-01' and reportdate <'2021-04-01'
group by w.userid
order by fullname ;
And gives the following output:
The second select statement reads like this:
SELECT r.userid, sum(r.invoicetime)/60 as invoicetime FROM apticproject.view_registeredtime as r
inner join user u on u.userid=r.userid
left join teammembers m on m.member=r.userid
left join teams t on t.teamid=m.team
where fromdate >= '2021-03-01' and fromdate <'2021-04-01' and r.invoiced=1 and r.approved=1 and charge_customer=1 and r.zeroinvoice=0
group by userid
order by fullname;
And gives the following output:
I want to be able to join the invoicetime column from the second select statement to the first select statement so that the invoicetime column is shown after the Worked column in the first select statement. As you can see I have the userid which can be used as a connection point. What is the most efficient way to do this? Your help is much appreciated.
I managed to find a solution as shown below. In MySQL you don't have a FULL JOIN, only Union exists, and this is the syntax I have used:
select x.userid, x.username, x.fullname,x.reportdate, x.teamname, x.Worked,y.invoicetime
from
(SELECT w.userid, u.username, u.fullname,w.reportdate, t.teamname, sum(w.worked)/60 as Worked FROM apticproject.view_workedtime as w
inner join user u on u.userid=w.userid
left outer join teammembers m on m.member=w.userid
left outer join teams t on t.teamid=m.team
where reportdate >= '2021-03-01' and reportdate <'2021-04-01'
group by w.userid) as x
left join
(SELECT r.userid, sum(r.invoicetime)/60 as invoicetime FROM apticproject.view_registeredtime as r
inner join user u on u.userid=r.userid
left join teammembers m on m.member=r.userid
left join teams t on t.teamid=m.team
where fromdate >= '2021-03-01' and fromdate <'2021-04-01' and r.invoiced=1 and r.approved=1 and charge_customer=1 and r.zeroinvoice=0
group by userid) as y on y.userid=x.userid
Union
select x.userid, x.username, x.fullname,x.reportdate, x.teamname, x.Worked,y.invoicetime
from
(SELECT w.userid, u.username, u.fullname,w.reportdate, t.teamname, sum(w.worked)/60 as Worked FROM apticproject.view_workedtime as w
inner join user u on u.userid=w.userid
left outer join teammembers m on m.member=w.userid
left outer join teams t on t.teamid=m.team
where reportdate >= '2021-03-01' and reportdate <'2021-04-01'
group by w.userid) as x
right join
(SELECT r.userid, sum(r.invoicetime)/60 as invoicetime FROM apticproject.view_registeredtime as r
inner join user u on u.userid=r.userid
left join teammembers m on m.member=r.userid
left join teams t on t.teamid=m.team
where fromdate >= '2021-03-01' and fromdate <'2021-04-01' and r.invoiced=1 and r.approved=1 and charge_customer=1 and r.zeroinvoice=0
group by userid) as y on y.userid=x.userid
order by fullname;
If you don't care to see items from your second query that have no user records in the first, you can drop the union and the whole right join in the second half of Darko86's answer.

How to get just one row from a subquery?

I have query with 6 columns and also I want to get the sum of other tables columns.
I want the result of sub query to be in one row but it repeated.
select t.id, t.subject, t.created_at, u.name, l.name as l_name,
ty.name as t_name
,(select sum(new) from statuses ) as new
,(select sum(open) from statuses) as open
,(select sum(close) from statuses) as close
,(select sum(`delete`) from statuses) as `delete`
from tickets t
left join users u on u.id=t.user_id
left join levels l on l.id=t.level_id
left join types ty on ty.id=t.type_id
could you please help me?
You can use GROUP BY in that,
select t.id, t.subject, t.created_at, u.name, l.name as l_name,
ty.name as t_name
,(select sum(new) from statuses ) as new
,(select sum(open) from statuses) as open
,(select sum(close) from statuses) as close
,(select sum(`delete`) from statuses) as `delete`
from tickets t
left join users u on u.id=t.user_id
left join levels l on l.id=t.level_id
left join types ty on ty.id=t.type_id GROUP BY u.name;

1054 error with nested query with right join

I would like to display a count of tickets per staff member while showing current tickets.
SELECT s.firstname, s.lastname, t.ticket_id, o.id, t.created FROM ost_ticket t
JOIN ost_staff s ON t.staff_id = s.staff_id
JOIN ost_user u ON t.user_id = u.id
JOIN ost_organization o ON u.org_id = o.id
RIGHT JOIN (
SELECT COUNT(tt.ticket_id)
FROM ost_ticket tt) a ON t.ticket_id = a.ticket_id WHERE...
I'm getting a Error in query (1054):
Unknown column 'a.ticket_id' in 'on clause'.
You need to select ticket_id in the subquery if you want to refer to it on the outside.
RIGHT JOIN
(
SELECT ticket_id, COUNT(ticket_id) as cnt
FROM ost_ticket
GROUP BY ticket_id
) a ON t.ticket_id = a.ticket_id

Report Query for multiple subqueries

Getting multiple records from table with subquery joins
SELECT
COUNT(*) AS total_count,
(SELECT
chat_box.user_id,
chat_box.message,
members.id,
members.display_name
FROM chat_box INNER JOIN members
ON chat_box.user_id = members.id
ORDER BY chat_id DESC LIMIT 1),
(SELECT COUNT(DISTINCT user_id) FROM chat_box) AS users_count
FROM chat_box
This is what I have so far, I want to get the members.display_name from the inner join where the chat_box.user_id = members.id as an output along aside the chat_box.message and save members.display_name and chat_box.message to a variable. Any help is appreciated.
It is not exactly clear what you are trying to do, but it seems like you could use something like this:
select u.user_id,
u.message,
u.id,
u.display_name,
cb1.total_count,
cb1.users_count
from
(
SELECT cb.user_id ,
cb.message,
m.id,
m.display_name
FROM chat_box cb
INNER JOIN members m
ON cb.user_id = m.id
) u
CROSS JOIN
(
select COUNT(*) AS total_count,
COUNT(DISTINCT user_id) AS users_count
FROM chat_box
) cb1

How to use aliases with MySQL LEFT JOIN

My original query is doing joins using the WHERE clause rather than JOIN. I realized that this was not returning movies that did not have any stars or genres did not show up so I think I have to do a LEFT JOIN in order to show every movie. Here is my original SQL:
SELECT *
FROM movies m, stars s, stars_in_movies sm, genres g, genres_in_movies gm
WHERE m.id = sm.movie_id
AND sm.star_id = s.id
AND gm.genre_id = g.id
AND gm.movie_id = m.id
AND m.title LIKE '%the%'
AND s.first_name LIKE '%Ben%'
ORDER BY m.title ASC
LIMIT 5;
I tried to do a LEFT JOIN on movies I'm definitely doing something wrong.
SELECT *
FROM movies m, stars s, stars_in_movies sm, genres g, genres_in_movies gm
LEFT JOIN movies m1 ON m1.id = sm.movie_id
LEFT JOIN movies m2 ON m2.id = gm.movie_id
AND sm.star_id = s.id
AND gm.genre_id = g.id
ORDER BY m.title ASC
LIMIT 5;
I get ERROR 1054 (42S22): Unknown column 'sm.movie_id' in 'on clause' so clearly I'm doing the join wrong, I just don't see what it is.
Don't mix the comma operator with JOIN - they have different precedence! There is even a warning about this in the manual:
However, the precedence of the comma operator is less than of INNER JOIN, CROSS JOIN, LEFT JOIN, and so on. If you mix comma joins with the other join types when there is a join condition, an error of the form Unknown column 'col_name' in 'on clause' may occur. Information about dealing with this problem is given later in this section.
Try this instead:
SELECT *
FROM movies m
LEFT JOIN (
stars s
JOIN stars_in_movies sm
ON sm.star_id = s.id
) ON m.id = sm.movie_id AND s.first_name LIKE '%Ben%'
LEFT JOIN (
genres g
JOIN genres_in_movies gm
ON gm.genre_id = g.id
) ON gm.movie_id = m.id
WHERE m.title LIKE '%the%'
ORDER BY m.title ASC
LIMIT 5;
You should put your conditions related to your JOINs in the same ON clause. However, for your above problem, you should use the following query:
SELECT *
FROM movies m
LEFT JOIN stars_in_movies sm ON sm.movie_id = m.id
JOIN stars s ON sm.star_id = s.id
LEFT JOIN genres_in_movies gm ON gm.movie_id = m.id
JOIN genres g ON gm.genre_id = g.id
ORDER BY m.title ASC
LIMIT 5;
Maybe ugly, But the way it will work is here. Beware this is ugly and lot of people is giving warning about this kind of hacks
SELECT *
FROM movies m, stars_in_movies sm LEFT JOIN movies m1 ON m1.id = sm.movie_id, stars s
ORDER BY m.title ASC
LIMIT 5;
when using joins, you must do the join with the right table which have the columns you are comparing.
SQL Join (inner join in MySQL)
select emp1.id,emp1.name,emp1.job from (select id, type as name, description as job from component_type as emp1)emp1
inner join
emp
on emp1.id=emp.id;
Left Join
select emp1.id,emp1.name,emp1.job from (select id, type as name, description as job from component_type as emp1 where id between '1' AND '5')emp1
left join
emp
on emp1.id=emp.id;
Right Join
select emp1.id,emp1.name,emp1.job from (select id, type as name, description as job from component_type as emp1)emp1
Right join
(select * from emp where id between '1' and '5')exe
on emp1.id=exe.id;
Using alias connect many table without using join..
select sum(s.salary_amount) as total_expenses_paid_to_all_department
from salary_mas_tbl s,dept_mas_tbl d
where s.salary_dept=d.dept_id;