I have the following table:
ID Category_ID Score Name
1 1 60 Name_1
2 1 50 Name_2
3 2 40 Name_3
4 3 30 Name_4
5 4 10 Name_5
lets say I run the following query:
SELECT * from table ORDER BY Score DESC LIMIT 0, 2
that will bring me:
ID Category_ID Score Name
1 1 60 Name_1
2 1 50 Name_2
How can I avoid having repeated Category_ID (as much as possible) in my results but having as 1st condition the ORDER BY Score. For example, how can I get the following instead:
ID Category_ID Score Name
1 1 60 Name_1
3 2 40 Name_3 <-- Following higher score with different Category_ID
and for
SELECT * from table ORDER BY Score DESC LIMIT 1, 2 the expected results are:
ID Category_ID Score Name
2 1 50 Name_2
4 3 30 Name_4
SELECT * from table ORDER BY Score DESC LIMIT 2, 2
the expected results are:
ID Category_ID Score Name
5 4 10 Name_5
Thank you!
You need to select only the ids that you want. This will require a join back to the original table. This version gives the result for the minimum id:
select t.*
from t join
(select category_id, min(id) as minid
from t
group by category_id
) tsum
on t.id = tsum.minid
order by max_score
limit 0, 2
If you want the maximum score, instead:
select t.*
from t join
(select category_id, max(score) as maxscore
from t
group by category_id
) tsum
on t.category_id = tsum.category_id and
t.score = tsum.maxscore
order by max_score
limit 0, 2
Of course, this assumes that the max score only appears on one record.
Related
SELECT * FROM table ORDER BY id ASC
Will output the full table:
id name weight
-- ---- ------
1 XXL 450
2 L 20
3 XL 30
4 XXL 875
5 S 2
Ordering by the weight and limiting to 3:
SELECT * FROM table ORDER BY weight DESC LIMIT 3
Will output:
id name weight
-- ---- ------
4 XXL 875
1 XXL 450
3 XL 30
I want to select all the rows that were not selected in the last query, as such:
id name weight
-- ---- ------
2 L 20
5 S 2
SELECT T.* FROM (
SELECT * FROM table ORDER BY weight DESC LIMIT 10 OFFSET 3
) AS T ORDER BY T.id
The inner query order the rows by weight and crop the results starting from the 4th row to the 13th. The outer query order the partial result by id.
I would just do:
select t.*
from t
where id not in (select id from t order by weight desc limit 3);
or:
select t.*
from t left join
(select id from t order by weight desc limit 3) tt
on t.id = tt.id
where tt.id is null;
However, you need to be very careful about what happens when two rows have the same weight. So, I would recommend these two queries:
select id
from t
order by weight desc, id
limit 3
select t.*
from t left join
(select id from t order by weight desc, id limit 3) tt
on t.id = tt.id
where tt.id is null;
I have a MySQL table
discount_vouchers
------------------
id
email
test_id
My goal is to list all vouchers that appears more than once with a given email and a given test_id from the GROUP BY:
GROUP BY email, test_id
HAVING count(*) >1
How to get read of this group by?
Here is an example:
discount_vouchers
------------------
1 1#test.com 20
2 1#test.com 10
3 1#test.com 20
4 2#test.com 30
I would like to have as a result:
id email test_id count
1 1#test.com 20 2
2 1#test.com 10 1
3 1#test.com 20 2
4 2#test.com 30 2
Try something like the following
SELECT C2, counter from
(SELECT C2, COUNT(*) as counter FROM test.mytable
GROUP BY C2) as aggregation
WHERE counter > 1
Without using group by, you can do something like
SELECT a.* ,
(SELECT count(*) FROM discount_vouchers b
WHERE a.email = b.email AND a.test_id = b.test_id) as count
FROM discount_vouchers a
How about this?
Aggregate using a subquery, and use its results in order to enrich the actual table:
SELECT `discount_vouchers`.*, `counts`.`count`
FROM `discount_vouchers`
INNER JOIN (SELECT `email`, `test_id`, Count(*) AS 'count'
FROM `discount_vouchers`) AS `counts`
ON `discount_vouchers`.`email` = `counts`.`email`
AND `discount_vouchers`.`test_id` = `counts`.`test_id`;
I am aggregating data and I cannot sum certain columns so I would like to take the most frequent observation from that column, or the median value. Example follows, thanks in advance.
ID site
1 3
1 3
1 2
1 3
2 4
2 5
2 5
2 5
I want it to look like
ID Site
1 3
2 5
WITH temp AS(
SELECT ID, Site, COUNT(*) As counts
FROM id_table
GROUP BY ID, Site
)
SELECT temp.ID, temp.Site
FROM temp
JOIN (SELECT ID, MAX(counts) max_counts
FROM temp
GROUP BY ID
)b
ON temp.ID = b.ID
AND temp.counts = b.max_counts
ORDER BY ID ASC
SQL Fiddle
This is a follow on from this question.
I want to get the game id that a player had his maximum score in. I am struggling to get the corresponding game_id column value when selecting the max(score)
My table is as follows:
id game_id player_id score
1 1 1 345
2 1 2 234
3 2 1 190
4 2 2 167
5 3 4 230
6 3 1 230
7 4 2 453
8 4 3 230
My query looks like this so far:
SELECT s.id, t.game_id, t.score
FROM (
SELECT game_id, score
FROM stats
WHERE player_id =2
) t
LEFT JOIN stats s on s.game_id = t.game_id AND s.score = t.score
WHERE s.player_id = 2
This gives me
id game_id score
2 1 234
4 2 167
7 4 453
I then need to join this whole query on as a subquery on the maximum score (id = 7), in order to then get the game_id, but I am not sure how to say join on this maximum value
here i have created sql feedle you can remove
SELECT s.id, t.game_id, t.score
FROM (
SELECT game_id, score
FROM game
WHERE player_id =2 order by score desc limit 0,1
) t
LEFT JOIN game s on s.game_id = t.game_id AND s.score = t.score
SELECT a.*
FROM TableName a
INNER JOIN
(
SELECT player_ID, MAX(Score) max_score
FROM TableName
GROUP BY Player_ID
) b ON a.Player_ID = b.player_ID AND
a.Score = b.max_score
Hope this can help you.
select game_id, player_id, score
from (
select rank() over (partition by player_id order by score desc) as rank_id, game_id, player_id, score
from stats
) a
where rank_id=1 and player_id = 2
I am writing a query to grab the items that a specific user_id was the first to use. Here is some sample data -
item_id used_user_id date_used
1 1 2012-08-25
1 2 2012-08-26
1 3 2012-08-27
2 2 2012-08-27
3 1 2012-08-27
4 1 2012-08-21
4 3 2012-08-24
5 3 2012-08-23
query
select item_id as inner_item_id, ( select used_user_id
from test
where test.item_id = inner_item_id
order by date_used asc
limit 1 ) as first_to_use_it
from test
where used_user_id = 1
group by item_id
It returns the correct values
inner_item_id first_to_use_it
1 1
3 1
4 1
but the query is VERY slow on a giant table. Is there a certain index that I can use or a better query that I can write?
i can't get exactly what you mean because in your inner query you have sorted it by their used_user_id and and on your outer query you have filtered it also by their userid. Why not do this directly?
SELECT DISTINCT item_id AS inner_item_id,
used_user_id AS first_to_use_it
FROM test
WHERE used_user_id = 1
UPDATE 1
SELECT b.item_id,
b.used_user_id AS first_to_use_it
FROM
(
SELECT item_ID, MIN(date_used) minDate
FROM tableName
GROUP BY item_ID
) a
INNER JOIN tableName b
ON a.item_ID = b.item_ID AND
a.minDate = b.date_used
WHERE b.used_user_id = 1