So I'm asked to try and convert this statement:
SELECT C.cid, C.cname
FROM Customer C, Buys B
WHERE C.cid = B.cid
GROUP BY C.cid
HAVING count(pid) > 100
to the same thing but not use the HAVING clause. I've been trying to figure it out for the last hour or so but am unsure on how to do this properly. I've been trying to figure out how to use the WHERE clause properly. You can only use the aggregate functions using the HAVING clause correct?
This is what the tables look like
Product(pid, name, price, mfgr)
Buys(cid, pid)
Customer(cid, cname, age)
Simply quoting #zfus answer in comment, just so this question appears to have an answer in the list to avoid further traffic.
SELECT cid, cname
FROM (
SELECT cid, cname, count(*) AS counter
FROM customer c
INNER JOIN buys b on (c.cid=b.cid)
GROUP BY cid, cname
) AS result
WHERE counter > 100
Related
How to i get the top vendor for each country? I have this code and it shows the connection between the two tables, now I have to get the largest gmv per country.
Here is my working code:
SELECT DISTINCT a.country_name, b.vendor_name,
SUM(a.gmv_local) as total_gmw
from `my-project-67287.order1.order2`a
join `my-project-67287.vendor1.vendor2` b on a.vendor_id = b.id
group by a.country_name, b.vendor_name;
The top 3 should show this:
Assuming you can save that SELECT into a table called vendors, you need to use it as the subquery in the FROM clause.
You could use this:
SELECT vendors.country_name, vendors.vendor_name, MAX(vendors.total_gmw)
FROM
(
SELECT DISTINCT a.country_name, b.vendor_name,
SUM(a.gmv_local) as total_gmw
from `my-project-67287.order1.order2`a
join `my-project-67287.vendor1.vendor2` b on a.vendor_id = b.id
group by a.country_name, b.vendor_name
) AS vendors
GROUP BY vendors.country_name;
I must mention I have not tested your query, since I do not have your tables, so I assumed it's correct.
I only created the vendors table with the required fields and values from your picture. This should print:
SELECT odr.c_name,vdr.v_name,odr.gmv
FROM(
SELECT *
FROM(
SELECT c_name,v_id,gmv
FROM `order`
ORDER BY gmv DESC
)
GROUP BY c_name
)AS odr
LEFT JOIN vender AS vdr ON vdr.id = odr.v_id
GROUP BY odr.c_name
c_name short for country_name
I have 2 tables called 'table123' and 'table246'.
'table123' columns: 'ID', 'Dept_ID', 'First_Name', 'Surname', 'Salary', 'Address'.
'table246' columns: 'Dept_ID', 'Dept_Name'.
I want to find the Average Salary for each 'Dept_Name'. So I tried using the query below, which is an Equi-Join with a Sub-query:
SELECT Dept_Name, alt.Average_Salary AS Avg_Salary
FROM table123 a, table246 b,
(SELECT Dept_ID, AVG(Salary)Avg_Salary
FROM table123
GROUP BY Dept_ID)alt
WHERE a.Dept_ID = alt.Dept_ID
AND a.Salary = alt.Average_Salary
AND a.Dept_ID = b.Dept_ID;
However, when I run the above query, it gives the desired 2 column names 'Dept_Name' and 'Avg_Salary', but with no data in it (just a blank table).
What am I doing wrong in the code, which is causing this blank result table?
Also, is there an alternative method of getting the same result, using an Inner- Join? The Equi-Join is quite confusing.
Never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
Your query does not return results because no one has exactly the average value, so the salary condition fails. Based on what you are selecting, the subquery is the query you want:
SELECT Dept_ID, AVG(Salary) as Avg_Salary
FROM table123
GROUP BY Dept_ID;
Presumably, the other table brings in the name, so:
SELECT b.Dept_Name, AVG(a.Salary) as Avg_Salary
FROM table123 a JOIN
table246 b
ON a.Dept_ID = b.Dept_Id
GROUP BY b.Dept_Name;
What about:
SELECT Dept_Name, alt.Avg_Salary
FROM table246 b
INNER JOIN (SELECT Dept_ID, AVG(Salary)Avg_Salary
FROM table123
GROUP BY Dept_ID)alt ON B.DEPT_ID = ALT.DEPT_ID
Go through this maybe it will help you.
http://www.databasejournal.com/features/mysql/article.php/3835506/Fetching-Data-from-Multiple-Tables-using-Joins.htm
I have the following data:
http://i.imgur.com/e4d8M8V.png?1
The first table is labeled "Offering" and the second is labeled "Instructor."
I am trying to sum the salaries of all the professors who do not have their instructor ID appear in the offering table.
What I did first was generate a table that has the data I need in it:
select distinct i.InstructorID, i.Salary
from Instructor i
where i.InstructorID NOT IN (select o.InstructorID from Offering o);
Which gives me the desired result here:
http://i.imgur.com/rkFKseX.png?1
I then want to add these two salaries and have the result displayed in a single salary column. I've tried code like:
$MySQL:> select sum(i.Salary)
from Instructor i
where i.Salary in ( select distinct i.InstructorID, i.Salary
from Instructor i
where i.InstructorID NOT IN (select o.InstructorID from Offering o));
And get "SQLException: java.sql.SQLException: Operand should contain 1 co." However, I am not sure how to contain the result from my previous query to one column. The way I see it is if I was going to sum all of the salaries that were on the list and I just did a distinct Salary, it would only return three salaries rather than eight salaries, so it would be wrong to do that for my case too.
How would I add the two columns I have generated, and is there an easier way to complete my goal than the method I am using?
You can use subqueries. They are described by this article
You should be able to just wrap this in a sub query:
select SUM(Salary)
from (
select distinct i.InstructorID, i.Salary
from Instructor i
where i.InstructorID NOT IN (select o.InstructorID from Offering o)
)
This will work in SQL Server, I think it will work in MYSQL.
You could probably join the two table and then do a group By.
Something like
select sum(salary) from a, b where a.instructorid = b.instructorid and .....
I think this is what you're trying to do :
$MySQL:> select sum(i.Salary)
from Instructor i
where i.Salary in ( select distinct i.Salary
from Instructor i
where i.InstructorID NOT IN (select o.InstructorID from Offering o));
I bet InstructorID is a primary key in Instructor table and I think you don't need "distinct" in select distinct InstructorID, Salary from Instructor.
select sum(Salary)
from Instructor
where InstructorID not in (select InstructorID from Offering);
Please test 3 different approaches and choose the best.
NOT IN
SELECT SUM(i.Salary)
FROM Instructor i
WHERE i.InstructorID NOT IN (select o.InstructorID from Offering o);
LEFT JOIN with IS NULL
SELECT SUM(i.Salary)
FROM Instructor i LEFT JOIN Offering o USING(InstructorID)
WHERE o.InstructorID IS NULL;
NOT EXISTS
SELECT SUM(i.Salary)
FROM Instructor i
WHERE NOT EXISTS (SELECT 1 FROM Offering o WHERE o.InstructorID = i.InstructorID);
The query that I am trying to get is to "Show the agent with the most clients".
The tables that I am utilizing:
realtor(rid, fname, lname)
contract(contractid, buyrid, buycid)
property(pid, price, sellrid, sellcid)
What I am trying to do is make one table that has the buyrid and sellrid from contract and property and then count which rid is used the most. This is what I have that does not work:
SELECT r.rid, fname, lname
FROM realtor r, contract c, property p
WHERE r.rid = c.buyrid and r.rid = p.sellrid
GROUP BY c.buyrid, p.sellrid
HAVING count(*) >= ALL
(SELECT count(*)
FROM contract c, property p
GROUP BY c.buyrid, p.sellrid);
When I ran this in my database I got an empty set, which makes no sense. What am I doing wrong here? I have been working on this for a couple hours now and I am stuck, thanks for your help.
SELECT r.rid,
fname,
lname
FROM realtor AS r
INNER JOIN contract AS c ON r.rid=c.buyrid
INNER JOIN property AS p on r.rid=p.sellrid
GROUP BY r.rid
ORDER BY COUNT(*) DESC
LIMIT 1
I can't test this but here is what I'd be inclined to do:
SELECT r.rid,
fname,
lname,
count(*) AS clients
FROM realtor r
LEFT JOIN contract c
ON r.rid = c.buyrid
LEFT JOIN property p
ON r.rid = p.sellrid
WHERE coalesce(c.buyrid, p.sellrid) IS NOT NULL
GROUP BY r.rid
ORDER BY count(*) DESC
LIMIT 1
The LEFT JOINs combined with COALESCE require an agent to have at least one client, and the order by and the limit enforce a return of just a single row. I added the count(*) on the end to enable you to test the script a bit easier.
Courses (cid, cname, description)
Professors (pid, pname)
Teaching (tid, cid, pid, year, semester, department)
Students (sid, lname, fname, b_date, department)
Enrolled_stud (sid, tid, enrollment_date, grade, grade_date)
The Question: query all the students names who have the highest average:
SELECT a.sname,a.avg
FROM (SELECT s1.sname,avg(e.grade)AS avg
FROM Students s1
NATURAL JOIN EnrolledStudents e
GROUP BY s1.sid
) as a
where a.avg=(select max(a.avg))
you can see the results i get in my SQLFIDDLE, and you can see that i was doing something wrong, and i dont get what! it all seem correct to me...
Since it's for study, I'll post this hint first. Think about the where clause - a is the current row. Of course a.avg equals max(a.avg).
Update
Try the following:
SELECT s1.sname, avg(e.grade) AS avg
FROM Students s1
NATURAL JOIN EnrolledStudents e
GROUP BY s1.sid
HAVING avg = (SELECT avg(e.grade) AS avg
FROM EnrolledStudents e
GROUP BY e.sid ORDER BY avg DESC LIMIT 1);
Well if no one has a better looking answer that works, then that makes this the best answer:
SELECT s.sname
FROM Students s
NATURAL JOIN EnrolledStudents e
GROUP BY s.sid
HAVING avg(e.grade) >= ALL(SELECT AVG(e.grade)
FROM EnrolledStudents e
GROUP BY e.sid)