mySQL change multiple queries into single query - mysql

I have two mySQL tables:
tblcoach: contains fields (coachid,coachschoolid, otherstuff)
tblschool: contains fields (schoolid,schooldivision)
I am trying to get a list of schools that is limited to the only those schools that are in the same schooldivision as a coach.
This code I have works, but is there someway to produce a single mySQL query to achieve the same results?
SELECT #cs := coachschoolid FROM tblcoach c;
SELECT #sd := s.schooldivision FROM tblschool s WHERE s.schoolid = #cs;
SELECT s2.schoolid, s2.schoolname FROM tblschool s2 WHERE schooldivision = #sd

Nest the queries:
select schoolId, schoolname
from tblschool
where
schooldivision = (
select schooldivision from tblschool where schoolid = (
select coachschoolid from tblcoach
)
)

This seems like it would work only with 1 coach.
You can use a self-join to do this:
SELECT s2.schoolid, s2.schoolname
FROM tblschool s
INNER JOIN tblschool s2 on s.schooldivision = s2.schooldivision
WHERE s.schoolid = ?
Allows you to pass in the schoolID. If you want to pass in the coachID:
SELECT s2.schoolid, s2.schoolname
FROM tblschool s
INNER JOIN tblschool s2 on s.schooldivision = s2.schooldivision
INNER JOIN tblcoach c on c.coachschoolid = s.schoolid
WHERE c.coachid = ?

Related

How to SUM the result of two different SQL query?

I want to SUM these two different queries. I joined both with USING function. but it shows the two results in two different cells.
I need a single result to SUM these two queries where the answer should be 4069.
The CODE
SELECT COUNT(*) Active_Projects FROM
(SELECT ProjectID, ProjectStatusID, ClientID
FROM project) a
INNER JOIN
(SELECT ProjectStatusID, ClientID, ProjectStatusName
FROM ProjectStatus) b
ON (a.ProjectStatusID = b.ProjectStatusID AND a.ClientID = b.ClientID)
WHERE ProjectStatusName LIKE '%active%'
AND a.ClientID = 4
UNION
SELECT COUNT(*) Total_Projects
FROM Project
WHERE ClientID=4
Picture
Screenshot
Screenshot Here
Try this. select query1+ query2;
select (
SELECT COUNT(*) Active_Projects FROM
(SELECT ProjectID, ProjectStatusID, ClientID
FROM project) a
INNER JOIN
(SELECT ProjectStatusID, ClientID, ProjectStatusName
FROM ProjectStatus) b
ON (a.ProjectStatusID = b.ProjectStatusID AND a.ClientID = b.ClientID)
WHERE ProjectStatusName LIKE '%active%'
AND a.ClientID = 4
) + (
SELECT COUNT(*) Total_Projects
FROM Project
WHERE ClientID=4) ;

Alternative to Where Exist clause MySQL

I have this select statement that is taking quite a while to run on a larger dataset
select lookup_svcscat_svcscatnew.SVCSCAT_NEW_DESC as svc_type,
enrolid, msclmid, dx1, dx2, dx3,
proc1,msk_cpt_mapping.surg_length_cd as SL_CD,
msk_cpt_mapping.days as day_window,o.svcdate_form, pay,
table_label
from ccaeo190_ky o
left join lookup_svcscat_svcscatnew on o.svcscat = lookup_svcscat_svcscatnew.svcscat
left join msk_cpt_mapping on o.proc1 = msk_cpt_mapping.cpt_code
where EXISTS
(
select 1
from eoc_op_mapping e
where e.msclmid = o.msclmid
and e.enrolid = o.enrolid
and proc1 =27447
)
ORDER BY svcdate_form, msclmid;
I want to return any row in my ccaeo190_ky table that meets the requirements of the where EXISTS clause on table eoc_op_mapping. Is there any way to achieve these results using joins or select statements?
I was thinking something like:
select lookup_svcscat_svcscatnew.SVCSCAT_NEW_DESC as svc_type,
o.enrolid, o.msclmid, dx1, dx2, dx3,
proc1,msk_cpt_mapping.surg_length_cd as SL_CD,
msk_cpt_mapping.days as day_window,o.svcdate_form, pay,
table_label
from ccaeo190_ky o
left join lookup_svcscat_svcscatnew on o.svcscat = lookup_svcscat_svcscatnew.svcscat
left join msk_cpt_mapping on o.proc1 = msk_cpt_mapping.cpt_code
inner join
(select msclmid, SUM(IF(proc1 = 27447,1,0)) AS cpt
from eoc_op_mapping
group by enrolid
HAVING cpt > 0) e
on e.enrolid = o.enrolid
group by o.enrolid;
But I don't know if this is in the right direction
Usually EXISTS performs better than a join.
If you want to try a join, this the equivalent to your WHERE EXISTS:
.......................................................
inner join (
select distinct msclmid, enrolid
from eoc_op_mapping
where proc1 = 27447
) e on e.msclmid = o.msclmid and e.enrolid = o.enrolid
.......................................................
You can remove distinct if there are no duplicate msclmid, enrolid combinations in eoc_op_mapping.

MYSQL - CONCATENATE a lookup tables columns into one row

I have the following table structure:
tbl_catalogue_state
In tbl_catalogue there is a part number 58674 that has three states in the tbl_catalogue_state_lk table. Here is the result when I run a query inner joining the three tables.
As expected there are multiple rows returned.
Is there a way to only return one row having the values for each catalgue_state_id on the same row?
I would also like the ability to ignore a row for example:
select tbl_catalogue.catalogue_part, tbl_catalogue_state.catalogue_state_id from tbl_catalogue
inner join tbl_catalogue_state_lk on tbl_catalogue.catalogue_id = tbl_catalogue_state_lk.catalogue_id
inner join tbl_catalogue_state on tbl_catalogue_state_lk.catalogue_state_id = tbl_catalogue_state.catalogue_state_id
where tbl_catalogue_state_lk.catalogue_state_id <> 1;
The above select still returns two rows.
UPDATE
I was able to use GROUP_CONCAT:
select tbl_catalogue.catalogue_part, GROUP_CONCAT(tbl_catalogue_state.catalogue_state_id) as cat_state from tbl_catalogue
inner join tbl_catalogue_state_lk on tbl_catalogue.catalogue_id = tbl_catalogue_state_lk.catalogue_id
inner join tbl_catalogue_state on tbl_catalogue_state_lk.catalogue_state_id = tbl_catalogue_state.catalogue_state_id
where tbl_catalogue_state_lk.catalogue_state_id <> 1
group by tbl_catalogue.catalogue_id;
My issue is the above statement still returns a row. I need it to return nothing.
I was able to use not exists:
select tc.catalogue_part, GROUP_CONCAT(tcs.catalogue_state_id) as cat_state from tbl_catalogue as tc
inner join tbl_catalogue_state_lk as tcsl on tc.catalogue_id = tcsl.catalogue_id
inner join tbl_catalogue_state as tcs on tcsl.catalogue_state_id = tcs.catalogue_state_id
where
not exists
(
select tcsl2.catalogue_state_id from tbl_catalogue_state_lk as tcsl2
where tcsl2.catalogue_state_id = 6 and tcsl2.catalogue_id = tc.catalogue_id
)
and
not exists
(
select tcsl3.catalogue_state_id from tbl_catalogue_state_lk as tcsl3
where tcsl3.catalogue_state_id = 1 and tcsl3.catalogue_id = tc.catalogue_id
)
and
not exists
(
select tcsl3.catalogue_state_id from tbl_catalogue_state_lk as tcsl3
where tcsl3.catalogue_state_id = 2 and tcsl3.catalogue_id = tc.catalogue_id
)
group by tc.catalogue_id;

INTERSECT query in MariaDB

I have a problem with this query in MariaDB language. I want to do an intersect with the same field but with two values. The problem is that i can't use the INTERSECT query.
How can I do it?? I have tried with exists and inner join but it still doesn't work.
SELECT nombre
FROM actores
WHERE codactor IN ( SELECT actor
FROM participacion
WHERE (titulo,año) IN (SELECT titulo, año
FROM peliculas
WHERE director IN (
SELECT coddirector
FROM directores d
WHERE d.nombre='Alejandro'
AND d.apellido='Amenabar')))
INTERSECT
SELECT nombre
FROM actores
WHERE codactor IN ( SELECT actor
FROM participacion
WHERE (titulo,año) IN (SELECT titulo,año
FROM peliculas
WHERE director in (
SELECT coddirector
from directores p
WHERE p.nombre='Pedro'
AND p.apellido='Almodobar')));
INTERSECT was introduced in MariaDB 10.3.0.
INTERSECT
The result of an intersect is the intersection of right and left SELECT results, i.e. only records that are present in both result sets will be included in the result of the operation.
(SELECT e_name AS name, email FROM employees)
INTERSECT
(SELECT c_name AS name, email FROM customers);
As for your query you could leave it as is.
First try it like this, to check you have all the actors. I have to add codactor in case you have actors with same name.
SELECT a.codactor, a.nombre -- add ', *' to see all columns and test query is ok.
FROM actores a
JOIN participacion p
ON a.codactor = p.actor
JOIN peliculas m
ON p.titulo = m.titulo
AND p.ano = m.ano
JOIN directores d
ON p.director = d.coddirector
WHERE (d.nombre = 'Alejandro' and d.apellido = 'Amenabar')
OR (d.nombre = 'Pedro' and d.apellido = 'Almodobar')
Then add GROUP BY to see which actor are in movies from both directors.
GROUP BY a.codactor, a.nombre
HAVING COUNT(DISTINCT coddirector) = 2

Troubles with nested queries

I have this query which works perfectly:
SELECT *
FROM Customer
WHERE SacCode IN
(
SELECT SacCode
FROM SacCode
WHERE ResellerCorporateID = 392
ORDER BY SacCode
)
AND CustomerID IN
(
SELECT CxID
FROM CustAppointments
WHERE AppRoomID IN
(
SELECT AppRoomID
FROM ClinicRooms
WHERE ClinID IN
(
SELECT ClinID
FROM AppClinics
WHERE ClinDate >='20090101'
AND ClinDate <='20091119'
)
)
)
However, I need to see the value of ClinDate (inside the last nested query)...
How do I do it?
Thanks.
I'd rewrite the query using joins. Then, you can access any data from any of the joined tables.
For example, you could rewrite your query like this:
SELECT c.*, ac.ClinDate
FROM Customer c
JOIN SacCode sc ON sc.SacCode = c.SacCode
JOIN CustAppointments ca ON ca.CustomerID = c.CustomerID
JOIN ClinicRooms cr ON cr.AppRoomID = ca.AppRoomID
JOIN AppClinic ac ON ac.ClinID = cr.ClinID
WHERE ac.ClinDate >='20090101'
AND ac.ClinDate <='20091119'
AND sc.ResellerCorporateID = 392
Think I'd use derived table in the FROM statement rather than 3 deep nested query, will allow you to access values and will look a LOT better.
You'll need to copy the subselects to the FROM clause or rewrite the query using JOINs.
it should look something like this:
SELECT c.*, a.ClinDate
FROM Customer c
inner join CustAppointments ca
inner join ClinicRooms cr
inner join AppClinics a
where c.SacCode IN
(
SELECT SacCode
FROM SacCode
WHERE ResellerCorporateID = 392
ORDER BY SacCode
)
and c.CustomerID = ca.CxID
and ca.AppRoomID = cr.AppRoomID
and cr.ClinID = a.ClinID
and a.ClinDate >='20090101'
and a.ClinDate <='20091119'