Is there any other way to write this query ?
I tried doing it in a subquery but it doesn't work because of the multiple columns. It seems like this query only works by itself. Please correct me
Records
PK recordId
dateViewed
CarViewed
I tried this
SELECT R.`dateViewed` FROM Records ,(
SELECT R.CarViewed, COUNT(R.CarViewed) as cnt FROM Records R
GROUP BY R.CarViewed
ORDER BY cnt DESC
LIMIT 1 ) AS favouriteCarOfTheDay
GROUP BY R.`dateViewed
Then I tried this
SELECT R.`dateViewed` ,COUNT(R.CarViewed) as cnt FROM Records ,
(
SELECT R.CarViewed FROM Records R
GROUP BY R.CarViewed
ORDER BY cnt DESC
LIMIT 1 ) AS favouriteCarOfTheDay
GROUP BY R.`dateViewed
Along many other queries I tried, I have no idea how to get it working.
In a nutshell for a specific date, I would like to get the most common cars that were viewed.
Like :
dateViewed favouriteCarOfTheDay
2012-09-22 | Nissan
2012-09-23 | BMW
try this
SELECT R.`dateViewed` ,COUNT(R.CarViewed) as cnt ,R.CarViewed FROM Records R
GROUP BY R.`dateViewed
ORDER BY COUNT(R.CarViewed) DESC
I think the following should work (disclaimer, not all my own work, adapted from an answer at another question)
SELECT DISTINCT
R.dateViewed,
R.CarViewed
FROM Records R
WHERE
R.dateViewed =
(SELECT R2.dateViewed FROM
(
SELECT R1.dateViewed, COUNT(*) AS numViewed
FROM Records R1
WHERE R1.CarViewed = R.CarViewed
GROUP BY R1.dateViewed
ORDER BY R1.numViewed DESC
) AS R2
LIMIT 1
)
ORDER BY r.dateViewed
Such things are really awful to do in MySQL so it might actually by slower than two correlated subquery but at least it returns both the car and it's viewcount:
SELECT counts.`dateViewed`,counts.`CarViewed` as favourite_car, counts.cnt
FROM
(SELECT R.`dateViewed` ,R.`CarViewed`, COUNT(*) as cnt
FROM Records
GROUP BY R.`dateViewed` ,R.`CarViewed`
) as counts JOIN
(SELECT R.`dateViewed`, MAX(cnt) as cnt
FROM
(SELECT R.`dateViewed` ,R.`CarViewed`, COUNT(*) as cnt
FROM Records
GROUP BY R.`dateViewed` ,R.`CarViewed`
) as q
GROUP BY R.`dateViewed`) as maxes
ON counts.cnt=maxes.cnt
Related
I've got this table called player_mast in a db (data are just an example), and I want to find the club which supplied the most number of players to the 2016 EURO cup.
player_id
country_id
jersey_no
player_name
posi_to_play
dt_of_bir
age
playing_club
1231
1231
10
Hazard
striker
2/3/1991
33
Chelsea
Why this query doesn't work? It seems right to me:
SELECT playing_club, MAX(NumberOfPlayerForTeam)
FROM (
SELECT playing_club, COUNT(player_id) AS NumberOfPlayerForTeam
FROM player_mast
GROUP BY(playing_club))
GROUP BY(playing_club);
Try this
SELECT playing_club, NumberOfPlayerForTeam<br>
FROM (<br>
SELECT playing_club, COUNT(player_id) AS NumberOfPlayerForTeam<br>
FROM player_mast<br>
GROUP BY(playing_club))<br>
ORDER BY NumberOfPlayerForTeam DESC LIMIT 1;
If you want the playing clubs that have the most rows in your table, you can use rank():
SELECT pm.*
FROM (SELECT playing_club, COUNT(*) AS NumberOfPlayerForTeam,
RANK() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM player_mast
GROUP BY playing_club
) pm
WHERE seqnum = 1;
Note:
COUNT(<column name>) counts the number of non-NULL values in the column. There is no need to do this additional check; COUNT(*) does what you want.
Parentheses are not needed around the GROUP BY keys.
Playerbase have 3 columns: PlrName, TeamTag, Score
I need to sort players grouping them by TeamTag. And put teams with best summarized score above.
So want to figure out what query will help make this:
PlrName|TeamTag|Score PlrName|TeamTag|Score
-------------------------------------------------------
Player1|TeamThr|0 Player6|TeamThr|9 \
Player2|TeamTwo|2 Player1|TeamThr|0 > 9
Player3|TeamOne|4 Player4|TeamThr|0 /
Player4|TeamThr|0 Player5|TeamOne|4 \
Player5|TeamOne|4 became-> Player3|TeamOne|4 > 8
Player6|TeamThr|9 Player8|TeamOne|0 /
Player7|TeamTwo|2 Player2|TeamTwo|2 \
Player8|TeamOne|0 Player7|TeamTwo|2 > 6
Player9|TeamTwo|2 Player9|TeamTwo|2 /
added:
With this query i can get an array(?) of TeamTag's ordered by team score:
SELECT TeamTag FROM Playerbase GROUP BY team ORDER BY SUM(Score) DESC
..can I sort then PlayerBase using this "array"? Prefably within one query :)
Also i need to get full lines (using *), not only three fields.
If your dbms doesn't support window functions (any MySQL version below 8.0):
SELECT PlrName, TeamTag, Score FROM table a
LEFT JOIN
(SELECT PlrName, TeamTag, Score ,SUM(score) ts FROM table GROUP BY TeamTag) b
ON a.TeamTag=b.TeamTag
ORDER BY b.ts DESC, a.TeamTag, score DESC;
Try this
; with cte as (
select TeamTag, sum(Score) as Sum
from tablename)
select t.PlrName, t.teamtag, t.Score from tablename as t inner join cte as c
on t.teamtag=c.teamtag order by c.sum desc, t.score desc
Assuming your dbms supports window functions
select PlrName, TeamTag, Score
from (
select PlrName, TeamTag, Score, sum(Score) over (partition by TeamTag) ms
from tablename ) t
order by ms desc, TeamTag, Score desc
EDIT changed max() to sum() as OP refined the problem explanation.
I made it like this, but feel little uncomfortable about sql :D
SELECT * FROM `Playerbase` as T1
JOIN
(SELECT TeamTag, SUM(Score) AS Sum FROM `Playerbase` GROUP BY TeamTag ORDER BY Sum DESC) AS T2
ON T2.TeamTag = T1.TeamTag
Didn't make what i was trying to, but anyway thanks for answers. They helped me to understand a bit more :D
I'm a beginner at SQL, how do I get a query which returns the most prevalent column value? Probably there is an answer somewhere but I don't know how to google it.
For example in the user_id column the query should return the value 1 because this is the most prevalent number.
One approach is to do a GROUP BY aggregation and then apply a LIMIT trick:
SELECT user_id, COUNT(*) AS cnt
FROM yourTable
GROUP BY user_id
ORDER BY COUNT(*) DESC
LIMIT 1;
If you want something more complex, then you would be getting into the realm of rank functionality. MySQL (at least as of the current release) does not support built-in rank support, so it can be tricky to perform such queries.
SELECT top 1 user_id, COUNT(*) AS cnt
FROM yourTable
GROUP BY user_id
ORDER BY COUNT(*) DESC
Have a common table expression that counts each user_id. Select user_id where the count is the max count. Will return both user_id's in case of a tie.
with cte as
(
SELECT user_id, COUNT(*) AS cnt
FROM yourTable
GROUP BY user_id
)
select user_id
from cte
where cnt = (select max(cnt) from cte)
I am having trouble writing a query for the following problem. I have tried some existing queries but cannot get the results I need.
I have a results table like this:
userid score timestamp
1 50 5000
1 100 5000
1 400 5000
1 500 5000
2 100 5000
3 1000 4000
The expected output of the query is like this:
userid score
3 1000
1 1000
2 100
I want to select a top list where I have n best scores summed for each user and if there is a draw the user with the lowest timestamp is highest. I really tried to look at all old posts but could not find one that helped me.
Here is what I have tried:
SELECT sum(score) FROM (
SELECT score
FROM results
WHERE userid=1 ORDER BY score DESC LIMIT 3
) as subquery
This gives me the results for one user, but I would like to have one query that fetches all in order.
This is a pretty typical greatest-n-per-group problem. When I see those, I usually use a correlated subquery like this:
SELECT *
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3;
This is not the whole solution, as it only gives you the top three scores for each user in its own row. To get the total, you can use SUM() wrapped around that subquery like this:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3) tmp
GROUP BY userId;
Here is an SQL Fiddle example.
EDIT
Regarding the ordering (which I forgot the first time through), you can just order by totalScore in descending order, and then by MIN(timestamp) in ascending order so that users with the lowest timestamp appears first in the list. Here is the updated query:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score, timeCol
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score) <= 3) tmp
GROUP BY userId
ORDER BY totalScore DESC, MIN(timeCol) ASC;
and here is an updated Fiddle link.
EDIT 2
As JPW pointed out in the comments, this query will not work if the user has the same score for multiple questions. To settle this, you can add an additional condition inside the subquery to order the users three rows by timestamp as well, like this:
SELECT userId, SUM(score) AS totalScore
FROM(
SELECT userId, score, timeCol
FROM myTable m
WHERE(
SELECT COUNT(*)
FROM myTable mT
WHERE mT.userId = m.userId AND mT.score >= m.score
AND mT.timeCol <= m.timeCol) <= 3) tmp
GROUP BY userId
ORDER BY totalScore DESC, MIN(timeCol) ASC;
I am still working on a solution to find out how to handle the scenario where the userid, score, and timestamp are all the same. In that case, you will have to find another tiebreaker. Perhaps you have a primary key column, and you can choose to take a higher/lower primary key?
Query for selecting top three scores from table.
SELECT score FROM result
GROUP BY id
ORDER BY score DESC
LIMIT 3;
Can you please try this?
SELECT score FROM result GROUP BY id ORDER BY score DESC, timestamp ASC LIMIT 3;
if 2 users have same score then it will set order depends on time.
You can use a subquery
SELECT r.userid,
( SELECT sum(r2.score)
FROM results r2
WHERE r2.userid = r.userid
ORDER BY score DESC
LIMIT 3
) as sub
FROM result r
GROUP BY r.userid
ORDER BY sub desc
You should do it like this
SELECT SUM(score) as total, min(timestamp) as first, userid FROM scores
GROUP BY userid
ORDER BY total DESC, first ASC
This is way more efficient than sub queries. If you want to extract more fields than userid, then you need to add them to the group by.
This will of cause not limit the number of scores pr user, which indeed seems to require a subquery to solve.
Have been reading for a few days now and can't seem to get hold of my problem here.
Let me give you an insight of my DB:
table1 codes:
id CODE
1 D0G08H13L12
2 D1G12H10L12
3 D0G10H12L11
4 D1G10H10L09
5 D0G08H13L12
6 D1G12H10L12
7 D0G08H13L12
8 D1G10H10L09
9 D0G08H13L12
10 D1G12H10L12
now I'm searching for a query to count which codes occurs the most after D0G08H13L12, so searching in the next record my answer from the query would be:
3 times D1G12H10L12
1 time D1G10H10L09
this is what I have until now, I think I have to use subquery but I'm not quite sure.
SELECT id, code, COUNT(code) FROM table1 WHERE id IN ($idprint +1) GROUP BY code
ORDER BY COUNT(code) DESC
can any of you DB pro's help me in the good direction?
Try this:
SELECT COUNT(id) tot, `code`
FROM your_table
GROUP BY `code`
HAVING tot <=
(SELECT COUNT(id) FROM your_table
WHERE code = 'D0G08H13L12')
AND code <> 'D0G08H13L12'
ORDER BY tot DESC
If you want to have only two records append this to the query:
LIMIT 2
Try this, This will give u the desired result....
Select id, code, count(code)
from table1
where id>(select max(id) from table1 where code =D0G08H13L12) group by code order by count(code) desc;
select min(x.id), x.code
from yourTable x,
(
select * from yourTable
where code = 'D0G08H13L12'
) v
where
x.id > v.id
group by v.id
To get the most next codes for entered one.