I allow myself to write a thread regarding a query I'm trying to make for hours now. I'm trying to get the name of the friend (friend.first_name) who refuses the most proposed dates for events.
To do this I'm counting the number of proposed date and ORDER BY ASC.
SELECT COUNT(*) 'NbrProposedDate', f.FIRST_NAME,
f.LAST_NAME, f.FRIEND_ID
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
ORDER BY NbrProposedDate ASC
LIMIT 1;
However, this does not take into account TIES.
What I'm looking for is the following result :
Furthermore, I've seen something with FETCH FIRST 1 ROW WITH TIES, however it does not seem to work with MySQL (getting SQL syntax issue).
Finally, I've had found an alternative using a function :
-- Find Minimum Count
SELECT MIN(cnt) INTO #min FROM (SELECT COUNT(*) cnt FROM PROPOSES NATURAL JOIN FRIEND f GROUP BY f.FRIEND_ID) t;
-- Show Friends with minimum count
DROP VIEW IF EXISTS troublemaker;
CREATE VIEW troublemaker AS
SELECT FIRST_NAME, LAST_NAME
FROM PROPOSES p
JOIN (SELECT FRIEND.FRIEND_ID
FROM PROPOSES
NATURAL JOIN FRIEND
GROUP BY FRIEND.FRIEND_ID
HAVING COUNT(*) = #min) t
ON p.FRIEND_ID = t.FRIEND_ID
JOIN FRIEND ON t.FRIEND_ID = FRIEND.FRIEND_ID
ORDER BY p.FRIEND_ID ASC;
However, the issue is that, I need to put this into a view, but "View's SELECT contains a variable or parameter".
Therefore, I'm looking for another alternative or a solution to fix this issue.
P.S. : here is an MLD :
View is not required, a query result could be used as subquery
SELECT
COUNT(*) NbrProposedDate,
MAX(f.FIRST_NAME) FIRST_NAME,
MAX(f.LAST_NAME) LAST_NAME,
f.FRIEND_ID
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
HAVING COUNT(*) = (
SELECT COUNT(*)
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
ORDER BY COUNT(*)
LIMIT 1
)
On MySQL 8+, it can also use RANK()
WITH ranks AS (
SELECT
COUNT(*) NbrProposedDate,
MAX(f.FIRST_NAME) FIRST_NAME,
MAX(f.LAST_NAME) LAST_NAME,
f.FRIEND_ID,
RANK() OVER (ORDER BY COUNT(*) ASC) rk
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
)
SELECT * FROM ranks WHERE rk = 1
Related
I am working on this project at my university, where I need to create a query to the database. I want the query to return the company with most movies in the given genre. At the moment I have this query, but this only return one company, but there can probably be more than one.
SELECT CompanyID, CategoryID, COUNT(*) as NumberOfMovies
FROM Movie
NATURAL JOIN CategoryFilm
NATURAL JOIN Category
NATUAL JOIN Comapny
GROUP BY CategoryID, CompanyID
Order by NumberOfMovies DESC LIMIT 1
I beleave I will need a "having" in here.
pls try this, it may because you added limit 1, which only show 1st retrieved record
SELECT CompanyID, CategoryID, COUNT(*) as NumberOfMovies
FROM Movie
NATURAL JOIN CategoryFilm
NATURAL JOIN Category
NATURAL JOIN Comapny
GROUP BY CategoryID, CompanyID
Order by NumberOfMovies DESC
I assume by "category" you mean "genre" -- or that they are the same thing.
Do not use NATURAL JOIN. It does not even use properly declared foreign key relationships, instead relying merely on name similarity between tables. It is dangerous because the columns used are not specified and can introduce hard-to-debug errors. I often refer to it as an "abomination" because it does not take table declarations into account.
If you have a given category, then I would expect a WHERE clause:
SELECT CompanyID, COUNT(*) as NumberOfMovies
FROM Movie m JOIN
CategoryFilm cf
ON cf.movie_id = m.movie_id JOIN
Company c
ON c.company_id = m.company_id
WHERE cf.category_id = ?
GROUP BY CategoryID
ORDER BY NumberOfMovies DESC
LIMIT 1;
If you want to allow ties, you can use window function rank():
select *
from (
select
co.companyID,
ca.categoryID,
count(*) NumberOfMovies,
rank() over(partition by c.categoryID order by count(*) desc) rn
from movie m
inner join categoryFilm cf on cf.movieID = m.movieID
inner join category ca on ca.categoryID = cf.categoryID
inner join company co on co.companyID = m.companyID
group by co.companyID, ca.categoryID
) t
where rn = 1
order by ca.categoryID
This gives you the top company for each and every category, ties included. If you want to filter on a given category, you can just add a where clause to the inner query.
Side note: do not use natural joins: they are error-prone. I rewrote the query to use inner joins instead (I made a few assumptions on the relations).
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 know that this question is asked also before but i tried all of them but no one works for me because my query is a little bit different because it has sum function in query that needs to get sum and in base of sum to get the rank of the user.
So my question is how to find the rank for single user my table is this:
currently i am trying with this query but this gives me all users.
SELECT u.user_name as userName
, sum(taken_quiz_points) as totalPoints
FROM taken_quiz as q
, users_app as u
WHERE q.taken_quiz_user_id = u.user_id
GROUP
BY taken_quiz_user_id
ORDER
BY totalPoints DESC
First of all, you should use INNER JOIN when you query data from multiple tables.
Also, I don't think it's possible to ORDER BY an alias, you have to repeat the operation of the alias.
If you want to have the rank of a single user you have to add a WHERE condition, like WHERE u.name = "toto" or something.
You should end up with this :
SELECT
u.user_name as userName ,
sum(q.taken_quiz_points) as totalPoints
FROM taken_quiz q
INNER JOIN users_app u ON q.taken_quiz_user_id = u.user_id
WHERE u.name = "toto"
GROUP BY q.taken_quiz_user_id
ORDER BY sum(q.taken_quiz_points) DESC
So you need the whole dataset in order to know the ranking of the person. It's a bit ugly, but you can nest to get the ranking, and then select from the ranked dataset the person you are interested in:-
Select userName, user_rank from
(Select userName,totalpoints ,dense_rank() OVER (Order by totalpoints desc) as user_rank
from (
SELECT u.user_name as userName ,sum(taken_quiz_points) as totalPoints
FROM taken_quiz as q, users_app as u
WHERE q.taken_quiz_user_id=u.user_id GROUP BY user_name,
taken_quiz_user_id) aa
) bb
where userName ='bob'
I am a newbie in MYSQL and had a question regarding the use of MAX and COUNT functions together in MYSQL. I have 2 tables worker and assignment and the primary key of worker is a foreign key in assignment table.
I need to show the employees name and id and the total assignment assigned to him, and only show the person with the most assignment that is the employee with the most assignment.
my code is
SELECT worker.Wrk_ID, worker.Wrk_LastName, MAX(a.count_id)
FROM worker,
(SELECT COUNT(assignment.Wrk_ID) as count_ID
FROM worker, assignment
WHERE worker.Wrk_ID = assignment.Wrk_ID
GROUP BY worker.Wrk_ID)as a
GROUP BY worker.Wrk_ID;
The code is giving an error no. #1054.
Please can anyone help me.
Thanking you in anticipation.
Try something like this:
SELECT worker.Wrk_ID, worker.Wrk_LastName, S.Count
FROM worker
JOIN
(SELECT Wrk_ID, COUNT(*) AS Count FROM Assignments
GROUP BY Wrk_Id ORDER BY COUNT(*) DESC LIMIT 1) S
ON worker.Wrk_ID = S.Wrk_ID
If you want a list of employees sorted by their total assignments:
SELECT w.WrkID, w.Wrk_LastName, COUNT(*) AS Assignments
FROM work w left join Assignments a
ON w.WrkID=a.WrkID
GROUP BY w.WrkID
ORDER BY COUNT(*) DESC;
To allow multiple winners:
SELECT s.*, w.Wrk_Lastname FROM
(
SELECT wrk_id , COUNT(*) AS tot_assignments
FROM Assignments
GROUP BY wrk_id
HAVING COUNT(*) =
(
SELECT MAX(tot) FROM
(
SELECT COUNT(*) AS TOT FROM Assignments GROUP BY wrk_id
) counts
)
) winners
INNER JOIN worker w ON s.wrk_id = w.wrk_id;
It can be slow since it does multiple GROUP BY. Doing it in separated steps in a procedure can be better.
How could I find the most common value in table player_frags of either lasthit or mostdamage and order by asc?
SELECT DISTINCT(name) FROM players p
INNER JOIN player_frags pf ON pf.lasthit = p.name
OR pf.mostdamage = p.name
SELECT name FROM players p
INNER JOIN player_frags pf ON pf.lasthit = p.name
OR pf.mostdamage = p.name GROUP BY name Order By COUNT(*) DESC
You could add LIMIT 1 at the end for the most common name.
SQL Fiddle
I don't think you tried, this looks exactly like the other SQL you posted in the other question you sent
Anyway this will return name vs frequency of appearing:
SELECT COUNT(*) AS Freq, name
FROM players
GROUP BY players.name
ORDER BY COUNT(*)