Regarding group by inside inner join mysql - mysql

I am trying the below group by inside inner join in mysql. It's saying unknown column name. Could You please help me out regarding this. I am getting an error on this query "SELECT Min(Id) FROM testinbcalls group by lc.DBID" in the inner join saying "Unknown column name DBID in the groupby). Is there an alternative way I can modify this query if groupby is not allowed. I tried ""SELECT Min(Id) FROM testinbcalls WHERE Id= lc.DBID" instead of group by but it didn't work. I prefer not move the check to the where clause as i want the records to be filtered on the inner join itself. Could anyone help me out. Thanks
SELECT DISTINCT ic.Id as `Id`, lc.DBID,
init.Name as Init,
lc.TargetNumber as PhoneNumber,
CONCAT(us.FirstName,' ',us.Surname) as UserName,
iout.Name as Outc FROM
testcalls ic
INNER JOIN testinit init on ic.InitId=init.Id
INNER JOIN users us on ic.UserId=us.Id
INNER JOIN testinbcalls lc ON ic.Id=lc.CallId AND lc.DBID IS NOT NULL AND ic.Id=(**SELECT Min(Id) FROM testinbcalls group by lc.DBID** )
INNER JOIN (SELECT MIN(Id) Id FROM testinbcalls group by lc.DBID) mincallid ON ic.Id=mincallid.Id
INNER JOIN icomes iout on ic.OutId=iout.Id
WHERE ic.AssignedDateTime between '2015-06-08 00:00:00' and '2015-06-09 23:59:59' ORDER BY Id DESC limit 250;

You change it to below removing the table alias lc. With that you are actually referring the outer query table.
INNER JOIN (SELECT MIN(Id) AS MinId FROM testinbcalls group by DBID)

Related

Is it possible to select from the result of a subquery in a join

So I have a large subquery and I would like to join on that subquery while using the result of the subquery in the join.
For example, I have a table called patient and one called appointment, and I would like to get the number of appointments per patient with given criteria.
Right now I am doing something like this:
SELECT
t1.*
FROM
(
SELECT
patient.name,
patient.id,
appointment.date
FROM
patient
LEFT JOIN appointment ON appointment.patient_id = patient.id
WHERE
/* a **lot** of filters, additional joins, etc*/
) t1
LEFT JOIN (
SELECT
COUNT(*) number_of_appointments,
patient.id
FROM
patient
LEFT JOIN appointment ON appointment.patient_id = patient.id
GROUP BY
patient.id
) t2 ON t1.id = t2.id
The problem is that this returns the number of appointments for each patient independent from the subquery above it. I tried writing the join as this:
LEFT JOIN (
SELECT
COUNT(*) number_of_appointments,
patient.id
FROM
t1
GROUP BY
patient.id
)
But obviously I'm getting an error saying that table t1 doesn't exist. Is there any way for me to do this cleanly without having to repeat all of the filters from t1 in t2?
Thanks!
Why not use window functions?
SELECT p.name, p.id, a.date,
COUNT(a.patient_id) OVER (PARTITION BY p.id) as num_appointments
FROM patient p LEFT JOIN
appointment a
ON a.patient_id = p.id
WHERE . . .
This provides the count based on the WHERE filtering. If you wanted a count of all appointments, then do the calculation before applying the WHERE:
SELECT p.name, p.id, a.date,
COALESCE(a.cnt, 0) as num_total_appointments,
COUNT(a.patient_id) OVER (PARTITION BY p.id) as num_matching appointments
FROM patient p LEFT JOIN
(SELECT a.*,
COUNT(*) OVER (PARTITION BY a.patient_id) as cnt
FROM appointment a
) a
ON a.patient_id = p.id
WHERE . . .

MySQL - Ordering IN within INNER JOIN

I'm creating a system that allows a user to search a database of photo albums images for a keyword, it's working great, the only issue is that I'm ordering relevancy by the amount of times that keyword appears in an album. I'm doing this using:
SELECT collections_ids.collection_id
FROM `keywords`
INNER JOIN collections_ids ON keywords.id = collections_ids.photo_id
WHERE keywords.`keyword` = 'trees'
GROUP BY collection_id
ORDER BY COUNT(*) DESC
As said, this works great.
The only issue is, when this is included in an "WHERE IN" query, it loses it's order and is returned randomly. For clarity, here is the query:
SELECT collections.id,
collections.title
images.img_small
FROM `collections`
INNER JOIN images ON images.id = collections.cover_photo
WHERE collections.`id` IN
(SELECT collections_ids.collection_id
FROM `keywords`
INNER JOIN collections_ids ON keywords.id = collections_ids.photo_id
WHERE keywords.`keyword` = 'trees'
GROUP BY collection_id
ORDER BY COUNT(*) DESC)
I've tried researching, and people have suggested using the FIELD function, but I don't see that working in this context.
Any suggestions?
you can use sub query as join and take it count(*) as order by like below
SELECT collections.id,
collections.title
images.img_small
FROM `collections`
INNER JOIN images ON images.id = collections.cover_photo
INNER JOIN
(SELECT distinct collections_ids.collection_id As collection_id,COUNT(*) as total
FROM `keywords`
INNER JOIN collections_ids ON keywords.id = collections_ids.photo_id
WHERE keywords.`keyword` = 'trees'
GROUP BY collection_id
) as A
ON A.collection_id =collections.collection_id
order by A.total

Sub Query and JOINs

I have 3 tables concerning complains. The first table consists of the complain information itself, 2nd one is the complain_review with status_id, and the 3rd is the status_id table consisting status information. I'm trying to select the complain_desc from complain and latest status_id from complain_review (sort by date desc) and couple that with complain_status information.
This is what I've tried (no success so far):
SELECT c1.complain_desc, c2.status_id, c2.name as statusDesc from complain c1
left join
(SELECT c3.status_id, c4.name, c3.complain_id FROM complain_review c3
inner join complain_status c4 on c4.id=c3.status_id ORDER by c3.date DESC) c2
on c2.complain_id=c1.id
this is the updated example provided by #maheshiv
.. I've searched through the site but I don't exactly know what keyword to search concerning this matter :(
Edit: I've build a schema at http://sqlfiddle.com/#!9/d86a7a/2 so perhaps somebody could give take a better look at the tables
Edit: Perhaps this would be the closest as I could get .. and working!
SELECT c.complain_desc, cr1.status_id, cs.name
FROM complain c
INNER JOIN complain_review cr1 ON c.id=cr1.complain_id
INNER JOIN complain_status cs ON cs.id=cr1.status_id
WHERE cr1.date = (SELECT MAX(cr2.date) FROM complain_review cr2
WHERE cr1.complain_id=cr2.complain_id)
I'm trying to select the complain_desc from complain and latest status_id from complain_review (sort by date desc) and couple that with complain_status information.
This is a very common question on Stack Overflow. You can follow the greatest-n-per-group to find many solutions.
Here's a solution using your example:
SELECT c.complain_desc, latest_cr.status_id, cs.name AS status_desc
FROM complain AS c
INNER JOIN (
SELECT complain_id, status_id
FROM (
SELECT cr.complain_id, cr.status_id,
IF(#cgroup=cr.complain_id, #rownum:=#rownum+1, 1) AS rownum,
(#cgroup:=cr.complain_id)
FROM (SELECT #cgroup:=0, #rownum:=1) AS _init
CROSS JOIN complain_review AS cr
ORDER BY cr.complain_id DESC, cr.date DESC
) AS n
WHERE n.rownum = 1
) AS latest_cr
ON c.id=latest_cr.complain_id
INNER JOIN complain_status AS cs
ON cs.id = latest_cr.status_id;
Here's a different solution using no subqueries:
SELECT c.complain_desc, cr1.status_id, cs.name AS status_desc
FROM complain AS c
INNER JOIN complain_review AS cr1
ON cr1.complain_id = c.id
LEFT OUTER JOIN complain_review AS cr2
ON cr2.complain_id = c.id AND (cr2.date > cr1.date OR cr2.date = cr1.date AND cr2.id > cr1.id)
INNER JOIN complain_status AS cs
ON cs.id = cr1.status_id
WHERE cr2.id IS NULL;
I think you may need this query,
I believe max status_id is the latest status for complaint. As per http://sqlfiddle.com/#!9/d86a7a/15
select c1.complain_desc, c2.status_id, c3.name from complain c1 inner join (select complain_id, max(status_id) from complain_review group by complain_id) c2 on c1.id=c2.complain_id inner join complain_status c3 on c3.id=c2.status_id;

SQL Server Join tables

I want each student's name, last payment date only. means only day.
I know i won't help you at all giving this code:
But you could try to learn something from it.
SELECT S.Id, S.Name, F.max_date, F.FeeAmt
FROM tbl_student As S
INNER JOIN (
SELECT t.Id, MAX(t.Date) As max_date, t.FeeAmt FROM tbl_fees As t GROUP BY t.Id
) As F ON F.Id=S.Id
First we selected all users from tbl_student, and then we are joining fees, selecting max date and grouping by user. The result is last (date) fee per user.
Please try this query. I hope this should give you the expected output:
SELECT S.Name, T1.LastPaymentDate
FROM
(SELECT Id, Max([Date]) AS LastPaymentDate from tbl_fees GROUP BY Id) AS T1
INNER JOIN
tbl_student AS S
ON T1.Id = S.Id
SELECT S.name,SUB.LAST_DATE
FROM tbl_student S
JOIN (SELECT f.id AS ID,MAX(f.Date) AS LAST_DATE
FROM tbl_fees f
GROUP BY f.id) SUB
ON SUB.id = S.id

HQL and subqueries with joins

I've got the following sql query to retrieve the first row in each group ordered by date:
SELECT * FROM pls s1
INNER JOIN (
SELECT * FROM pls s2
ORDER BY s2.date DESC) a
ON (s1.id = a.id)
GROUP BY s1.name
Since joins with subqueries are not valid in HQL, how can it be modified?
Why not make that SQL statement a view?
create or replace view v_myview as
SELECT * FROM pls s1
INNER JOIN (
SELECT * FROM pls s2
ORDER BY s2.date DESC) a
ON (s1.id = a.id)
GROUP BY s1.name
Views can be mapped in the same manner as an entity, you just can't insert into them.