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.
Related
I'm having a problem in where i want to count how many medals in total a country has won from both the individual and team competitions does not give me the disered outcome. i have managed so far tocome up with this.
select distinct C.Cname as Country, count(i.medal) as Medals_Won
from individual_results as i, Country as C, participant as p
where (i.Olympian = p.OlympicID and C.Cname = p.country)
union
select distinct C.Cname, count(r.medal) as medals_Won
from team_results as r, Country as C, participant as p, team as t
where (r.team = t.TeamID and t.Member1 = p.OlympicID and C.Cname = p.Country)
group by C.Cname
order by medals_won desc
enter image description here
but i get this result.
even tho if i run the two separate pieces of code i ge the wanted restuls that is enter image description here
You say you can run your query and it gives you a result. This is bad. It indicates that you are MySQL's notorious cheat mode that lets you run invalid queries.
You have something like this:
select ...
union
select ...
group by ...
order by ...
There are two queries the results of which you glue together, namely
select ...
and
select ...
group by ...
So, your first query becomes:
select distinct C.Cname as Country, count(i.medal) as Medals_Won
from individual_results as i, Country as C, participant as p
where (i.Olympian = p.OlympicID and C.Cname = p.country)
You COUNT medals, i.e. you aggregate your data. And there is no GROUP BY clause. So you get one result row from all your data. You say you want to count all rows for which i.medal is not null. But you also want to select the country. The country? Which??? Is there just one country in the tables? And even then your query would be invalid, because still you'd have to tell the DBMS from which row to pick the country. You can pick the maximum country (MAX(C.Cname)) for instance or the minimum country (MIN(C.Cname)), but not the country.
The DBMS should raise an error on this invalid query, but you switched that off.
Make sure in MySQL to always
SET sql_mode = 'ONLY_FULL_GROUP_BY';
It is the default in more recent versions, so either you are working with old software or you switched from good mode to bad mode voluntarily.
And talking of old software: Even at the first moment MySQL was published, comma joins had long been deprecated. They were made redudant in 1992. Please don't ever use commas in your FROM clause. Use explicit joins ([INNER] JOIN, LEFT [OUTER] JOIN, etc.) instead.
As to the task, here is a straight-forward solution with joins:
select
c.cname as country,
coalesce(i.medals, 0) as medals_individual,
coalesce(t.medals, 0) as medals_team,
coalesce(i.medals, 0) + coalesce(t.medals, 0) as medals_total
from country c
left outer join
(
select p.country, count(ir.medal) as medals
from participant p
join individual_results ir on ir.olympian = p.olympicid
group by p.country
) i on on i.country = c.name
left outer join
(
select p.country, count(ir.medal) as medals
from participant p
join team t on t.member1 = p.olympicid
join team_results tr on tr.team = t.teamid
group by p.country
) t on on t.country = c.name
order by medals_total desc;
You should sum the union result for each of the subquery grouped by cname
select t.Cname , sum( t.Medals_Won)
from (
select C.Cname as Country, count(i.medal) Medals_Won
from individual_results i
inner join participant p ON i.Olympian = p.OlympicID
inner join Country C ON C.Cname = p.country
group by C.Cname
union
select distinct C.Cname, count(r.medal)
from team_results as r
inner join team as t ON r.team = t.TeamID
inner join participant as p ON t.Member1 = p.OlympicID
inner join Country as C ON C.Cname = p.Country
group by C.Cname
) t
group by t.Cname
order by sum( t.Medals_Won) desc
I am trying to get the data for the best 5 customers in a railway reservation system. To get that, I tried getting the max value by summing up their fare every time they make a reservation. Here is the code.
SELECT c. firstName, c.lastName,MAX(r.totalFare) as Fare
FROM customer c, Reservation r, books b
WHERE r.resID = b.resID
AND c.username = b.username
AND r.totalfare < (SELECT sum(r1.totalfare) Revenue
from Reservation r1, for_res f1, customer c1,books b1
where r1.resID = f1.resID
and c1.username = b1.username
and r1.resID = b1.resID
group by c1.username
)
GROUP BY c.firstName, c.lastName, r.totalfare
ORDER BY r.totalfare desc
LIMIT 5;
this throws the error:[21000][1242] Subquery returns more than 1 row
If I remove the group by from the subquery the result is:(its a tabular form)
Jade,Smith,1450
Jade,Smith,725
Jade,Smith,25.5
Monica,Geller,20.1
Rach,Jones,10.53
But that's not what I want, as you can see, I want to add the name 'Jade' with the total fare.
I just don't see the point for the subquery. It seems like you can get the result you want with a sum()
select c.firstname, c.lastname, sum(totalfare) as totalfare
from customer c
inner join books b on b.username = c.username
inner join reservation r on r.resid = b.resid
group by c.username
order by totalfare desc
limit 5
This sums all reservations of each client, and use that information to sort the resulstet. This guarantees one row per customer.
The query assumes that username is the primary key of table customer. If that's not the case, you need to add columns firstname and lastname to the group by clause.
Note that this uses standard joins (with the inner join ... on keywords) rather than old-school, implicit joins (with commas in the from clause: these are legacy syntax, that should not be used in new code.
I have a table with real estate agent's info and want to pull firstname, fullname, and email from rets_agents.
I want to then get a count of all of their sales from a different table called rets_property_res_mstr.
I created a query that doesn't work yet so I need some help.
SELECT r.firstname, r.fullname, r.email
from rets_agents r
LEFT JOIN rets_property_res_mstr
ON r.email = rets_property_res_mstr.ListAgentEmail
LIMIT 10;
I'm not sure how to get the count in this.
You seem to be looking for aggregation:
SELECT a.firstname, a.fullname, a.email, COUNT(p.ListAgentEmail) cnt
FROM rets_agents a
LEFT JOIN rets_property_res_mstr p ON r.email = p.ListAgentEmail
GROUP BY a.firstname, a.fullname, a.email
ORDER BY ?
LIMIT 10;
Note that, for a LIMIT clause to really make sense, you need a ORDER BY clause so you get a deterministic results (otherwise, it is undefined which records will be shown) - I added that to your query with a question mark that you should replace with the relevant column(s).
I would consider using a CTE for this:
WITH sales as (
SELECT ListAgentEmail, count(*) count_of_sales
FROM rets_property_res_mstr
GROUP BY ListAgentEmail
)
SELECT r.firstname, r.fullname, r.email, count_of_sales
from rets_agents r
LEFT JOIN sales
ON r.email = sales.ListAgentEmail
LIMIT 10;
I have this query that will return a list of all of the people associated with Thomas and their ids.
SELECT c.name, c.ID
FROM namesandID s, associations o, namesandID c
WHERE s.name='Thomas' AND o.id = s.ID AND o.associateID = c.ID
GROUP BY c.ID;
Then I have this query that I can manually type in the id number and it will return the correct count of associates.
SELECT count(*) FROM (
SELECT associateID FROM associations WHERE id=18827 GROUP BY associateID
) AS t;
My goal is to have one query that will take Thomas as the name and return three columns that will have his associate their id number an the number of people they are associated with.
Also as some additional information this is a very large database with about 4million rows and 300million associations so any speed increase on either of these queries would be greatly welcomed.
Not tested, however the below should work:
select
c.name,
c.id,
assoc_count.cnt
from
namesandIds s
inner join
associations o on
o.id = s.ID
inner join
namesandId c on
c.ID = o.associateId
left outer join
(
select
id,
count(distinct associateId) as cnt
from
associations
group by
id
) assoc_count on
assoc_count.id = c.ID
where
s.name = 'Thomas'
Not very efficient but
SELECT c.name, c.ID, COUNT(DISTINCT o.associateID)
FROM {the rest of the first query}
should do the trick.
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