mysql select statement for multiple table - mysql

This is just a test project. I want to know how to select All professors with more than 5 failed students in a subject
I already know how to select All professors with at least 2 subjects with the following query:
SELECT paulin_professors.*,
IFNULL(sub_p.total, 0) num
FROM paulin_professors
LEFT JOIN ( SELECT COUNT(*) total, pau_profid
FROM paulin_profsubject
GROUP BY pau_profid
) sub_p ON (sub_p.pau_profid = paulin_professors.pau_profid)
WHERE sub_p.total >= 2;
I know I'm close but I can't get it to work (All professors with more than 5 failed students in a subject) . Any ideas? TIA

try using SELECT with UNION
select [columnName1],[columnName2] from [Table1] where [condition] union select [columnName1],[columnName2] from [Table1] where [condition] union ....

Looks like can get the professor IDs from the profsubject table and JOIN the studentenrolled table using the subjid for the join. In a similar way to what you had, you can get the count of students who have a grade less than a certain pass/fail threshold (in this case 65).
Then to get a short list, you can select the distinct profids from this derivaed table.
SELECT
distinct pau_profid
FROM
(SELECT
t1.pau_profid,
IFNULL(t2.total_failed, 0) number_failed >= 5
FROM
paulin_profsubject t1
LEFT JOIN
(SELECT
COUNT(*) total_failed,
pau_subjid
FROM
paulin_studentenrolled
WHERE
pau_grade < 65
GROUP BY
pau_subjid
) t2
ON
t1.pau_subjid = t2.pau_subjid
WHERE
number_failed >= 5
) t3;

Related

How can I join SQL subqueries as they are?

I have 3 subqueries that when executed independently they all return 3 rows with the desired columns and values. Once I put them all in the from statement and select them all
SELECT
*,
ROUND(Verbrecher / Buerger * 100, 1) AS Sicherheitsgrad
FROM
(SELECT name AS Dorf
FROM dorf
GROUP BY dorfnr) AS Dorf,
(SELECT COUNT(*) AS Verbrecher
FROM bewohner
WHERE status LIKE 'boese'
GROUP BY dorfnr) AS Verbrecher,
(SELECT COUNT(*) AS Buerger
FROM bewohner
GROUP BY dorfnr) AS Buerger
This is the result of all three subqueries being respectively executed standalone
Standalone
This is the result
Snippet above being run
I expect them to be joined together and have three rows with the queries aligned horizontally.
That unfortunately is not the given result.
I hope this makes sense to a certain extent.
Maybe you need in this:
SELECT dorfnr, Dorf, Verbrecher, Buerger,
ROUND(Verbrecher / Buerger * 100, 1) AS Sicherheitsgrad
FROM ( SELECT dorfnr, name AS Dorf
FROM dorf
-- GROUP BY dorfnr
) AS Dorf
JOIN ( SELECT dorfnr, COUNT(*) AS Verbrecher
FROM bewohner
WHERE status LIKE 'boese'
GROUP BY dorfnr
) AS Verbrecher USING (dorfnr)
JOIN ( SELECT dorfnr, COUNT(*) AS Buerger
FROM bewohner
GROUP BY dorfnr
) AS Buerger USING (dorfnr)

mySQL: Select and a count(*) from different table?

I have two tables: 1 Table wccrm_orders where all orders are stored, and a table wccrm_kunden where all the user data is stored. In wccrm_orders, I have a date-field "ordered_date" and in wccrm_kunden a date-field "Anprobe"
When I want to select the wccrm_orders I use that code:
Select Year(wccrm_orders.ordered_date) as Jahr,
Month(wccrm_orders.ordered_date) as Monat, round(sum(wccrm_orders.preis)) as Summe,
count(*) as Anzahl from wccrm_orders
GROUP BY YEAR(wccrm_orders.ordered_date), MONTH(wccrm_orders.ordered_date)
When I want to count(*) all the appointments from wccrm_kunden.anprobe I use this code:
Select Year(wccrm_kunden.anprobe) as Jahr, Month(wccrm_kunden.anprobe) as
Monat, count(*) as Anzahl from wccrm_kunden where wccrm_kunden.status = 1
GROUP BY YEAR(wccrm_kunden.anprobe), MONTH(wccrm_kunden.anprobe)
How can I combine these codes? How can I achieve it, to get the numbers of trials (appointments) into the first SELECT?
Thank you very much for your help!
BR,
Stefan
A couple of sub-queries may work:
SELECT A.Jahr, A.Monat, A.Summe, A.Anzahl, B.AnzahlB
FROM
(SELECT Year(wccrm_orders.ordered_date) as Jahr,
Month(wccrm_orders.ordered_date) as Monat,
round(sum(wccrm_orders.preis)) as Summe,
count(*) as Anzahl
FROM wccrm_orders
GROUP BY
YEAR(wccrm_orders.ordered_date),
MONTH(wccrm_orders.ordered_date)) AS A
LEFT OUTER JOIN
(SELECT Year(wccrm_kunden.anprobe) as Jahr,
Month(wccrm_kunden.anprobe) as Monat,
count(*) as AnzahlB
FROM wccrm_kunden
WHERE wccrm_kunden.status = 1
GROUP BY
YEAR(wccrm_kunden.anprobe),
MONTH(wccrm_kunden.anprobe)) AS B
ON A.Jahr = B.Jahr AND A.Monat = B.Monat
(Sorry, don't have the schema for this DB, so there may be a syntax error (or three!) in this code, but hopefully you get the idea.)

SQL statement inside an SQL statement

I want this statement to return the systems where there are more than two stations, I got this far but I don't know what to do next. All this does it return every system with a regionID less than 1100001. Am I onto the right idea at least?
SELECT DISTINCT mapSolarSystems.regionID,solarSystemID,solarSystemName,x,z,security
FROM mapSolarSystems
WHERE mapSolarSystems.regionID <11000001
AND
2 < (SELECT COUNT(*) FROM stations,mapSolarSystems
WHERE mapSolarSystems.solarSystemID=stations.systemid)
See if this work:
SELECT DISTINCT mapSolarSystems.regionID,solarSystemID,solarSystemName,x,z,security
FROM mapSolarSystems m
join stations s on m.solarSystemID = s.systemid
WHERE mapSolarSystems.regionID <11000001
AND select COUNT(*) FROM stations >2
OR like that:
SELECT DISTINCT
mapSolarSystems.regionID,solarSystemID,solarSystemName,x,z,security
FROM mapSolarSystems m
join (select sistemId ,count(systemid) from station group by sistemId having
count(sistemId) > 2) X on m.solarSystemID = X.systemid
WHERE mapSolarSystems.regionID <11000001
SELECT DISTINCT m.regionID,solarSystemID,solarSystemName,x,z,security FROM mapSolarSystems m join stations s on m.solarSystemID = s.systemid WHERE m.regionID <11000001 AND (SELECT COUNT(*) FROM stations) >2

union of two select queries with different fields

I have two tables empmaster and allocation. I used union to do sql operation in order to get results from two tables. empmaster has empid and other empdetails. Table allocation contains empid from empmaster as foriegn key another field called per_alloc. I need to retrieve empdetails which satisfies:
empmaster.empid not in allocation.empid.
empmaster.empid in allocation.empid and allocation.per_alloc < 100.
MySQL query I used is:
select distinct(tbl_empmaster.emp_fname)
from tbl_empmaster
where tbl_empmaster.emp_id not in(select tbl_allocation.emp_id
from tbl_allocation)
union
select distinct(tbl_empmaster.emp_fname)
from tbl_empmaster
where tbl_empmaster.emp_id in(select tbl_allocation.emp_id
from tbl_allocation
group by emp_id
having sum(per_alloc) < 100)
This only retrieves empdetails, say tbl_empmaster.emp_fname, I need to retrieve sum(per_alloc) from select tbl_allocation!!! When I tried it gives lot of errors, Can any one show me the correct way, please?
Try this:
SELECT DISTINCT em.emp_fname, 0 alloc
FROM tbl_empmaster em
WHERE em.emp_id NOT IN(SELECT emp_id FROM tbl_allocation)
UNION
SELECT DISTINCT em.emp_fname, SUM(a.per_alloc) alloc
FROM tbl_empmaster em
INNER JOIN tbl_allocation a ON em.emp_id = a.emp_id
GROUP BY a.emp_id
HAVING SUM(a.per_alloc)<100
Ok, from what I have understood of your problem, I see two problems.
There is the unecessary grouping in the subquery of the second select statement. It should be ok to just write select tbl_allocation.emp_id from tbl_allocation where tbl_allocation.per_alloc<100)*
And the answer to your question.change the second select statement to the following, and it should work:select A.emp_fname, B.per_alloc from tbl_empmaster A join tbl_allocation B using(emp_id) where A.emp_id in(select C.emp_id from tbl_allocation C where C.per_alloc<100))
**Assuming that emp_id is the primary key*

left join multiplying values

I have the following queries -
SELECT COUNT(capture_id) as count_captures
FROM captures
WHERE user_id = 9
...returns 5
SELECT COUNT(id) as count_items
FROM items
WHERE creator_user_id = 9
...returns 22
I tried the following query -
SELECT COUNT(capture_id) as count_captures,
COUNT(items.id) as count_items
FROM captures
LEFT JOIN items ON captures.user_id = items.creator_user_id
WHERE user_id = 9
...but it returns two columns both with 110 as the value. I would want 5 in one column and 22 in the other. What am I doing wrong?
My knee-jerk is a subquery:
select count(capture_id) as count_captures,
(select count(id) as count_items
from items i where i.creator_user_id = captures.user_id) as count_items
from captures
where user_id = 9
I'm not really sure what you can do to avoid this. You're seeing expected (and generally desired behavior).
Of course, if you know that the ID's in both won't repeat themselves, you can use distinct:
SELECT COUNT( DISTINCT capture_id) as count_captures,
COUNT( DISTINCT items.id) as count_items
FROM captures
LEFT JOIN items ON captures.user_id = items.creator_user_id
WHERE user_id = 9
A LEFT JOIN returns each row in the left table with each row in the right table that matches the results. Since all of your id's are the same which produces a Cartesian Product of the table. (5 * 22 = 110).
This is expected to happen.
You could always union the results (warning, untested):
SELECT SUM(sub.count_captures), SUM(sub.count_items)
FROM (SELECT COUNT(capture_id) as count_captures, 0 as count_items
from captures where user_id = 9
UNION
SELECT 0 as count_captures, count(id) as count_items
from items where creator_user = 9) sub
Another way to combine two (seemingly not related) queries into one:
SELECT
( SELECT COUNT(capture_id)
FROM captures
WHERE user_id = 9
)
AS count_captures
, ( SELECT COUNT(id)
FROM items
WHERE creator_user_id = 9
)
AS count_items
There really is no need for subqueries or JOIN in these cases. Although the optimizer may be smart enough to figure that out, I wouldn't try to confuse him.