DataBase-Finding total scores - mysql

I've 15 levels, and each level consists of 2 rounds. Now I've to find the total score by finding the max score the user earned in round1 and round2 and calculate it. Likewise the same method up to how many levels he played. And, finally, the total result by calculating scores from all levels.
Can anyone please help me to find the total score using MySQL..!
I tried this code:
SELECT *, (classifica_score + MAX2) AS TOTAL FROM(
SELECT IFNULL( MAX(XX1.classifica_score), 0) AS classifica_score, XX1.classifica_level, XX1.classifica_round, XX1.fb_id,
(SELECT IFNULL( MAX(TC1.classifica_score), 0) FROM tab_classifica AS TC1 WHERE TC1.classifica_round = 2 AND TC1.fb_id = XX1.fb_id) AS MAX2
FROM tab_classifica AS XX1 WHERE XX1.classifica_round=1
GROUP BY XX1.classifica_level, XX1.classifica_round, XX1.fb_id
UNION ALL
SELECT IFNULL( MAX(XX2.classifica_score),0) AS classifica_score, XX2.classifica_level, XX2.classifica_round, XX2.fb_id,
(SELECT IFNULL( MAX(TC2.classifica_score),0) FROM tab_classifica AS TC2 WHERE TC2.classifica_round = 1 AND TC2.fb_id = XX2.fb_id ) AS MAX1
FROM tab_classifica AS XX2 WHERE XX2.classifica_round=2
GROUP BY XX2.classifica_level, XX2.classifica_round, XX2.fb_id
) AS TAB
my Db structure is as follows
classifica_id----- fb_id---classifica_nome----classifica_level----classifica_round---classifica_score

Related

Top 10 players with the highest batting average

Batting average = total number of runs scored / number of times out.
Here we need to make sure to include run outs (on non-striker end)
Output like :
Batsman_name Average
KL Rahul 44
Error:
Error in SQL statement: AnalysisException: cannot resolve 'batsman_runs' given input columns: [_auto_generated_subquery_name.Batsman]; line 1 pos 21;
'Sort ['Average DESC NULLS LAST], true
select Batsman_, sum(batsman_runs)/count(player_dismissed) as Average
from
(
(select batsman as Batsman_ from IPL_BALL_BY_BALL)
union all
(select non_striker as Batsman_ from IPL_BALL_BY_BALL)
)
group by Batsman_
order by Average desc;
because from your subquery ( result of union) you only returning "Batsman_" column. you have to retunr all the column you need :
select Batsman_, sum(batsman_runs)/count(player_dismissed) as Average
from
(
(select batsman as Batsman_,batsman_runs,player_dismissed from IPL_BALL_BY_BALL)
union all
(select non_striker as Batsman_,batsman_runs,player_dismissed from IPL_BALL_BY_BALL)
)
group by Batsman_
order by Average desc;
select Batsman_, sum(batsman_runs)/count(player_dismissed) as Average from
((select batsman as Batsman_,batsman_runs,player_dismissed from IPL_BALL_BY_BALL) union all (select non_striker as Batsman_,batsman_runs,player_dismissed
from IPL_BALL_BY_BALL))
group by Batsman_ order by Average desc;
You forgot fields "batsman_run & player_dismissed" in your inner sql

Same query returns different values on repeated execution

Database in use: 5.6 (I can't use LAG function which is from mysql 8)
I have the following table structure in mysql
book_id | Version | Rating | Price
varchar(25) | Decimal(10,2)| int | Decimal(10,2)
I have a web page where I show two charts.
In first chart, I will show count of books for rating(ratings are only from 1 to 4) but only of the latest versions. Query1
In second chart, I will show count of books in a price range but only of the latest versions. Query2
These two queries are ran one after the other every time the web page is loaded or refreshed. Although data remains constant, I get different results sometimes for the same query.
I have the following two queries which are almost identical
QUERY1
SELECT
SUM(CASE WHEN rating=1 THEN 1 ELSE 0) AS rating1,
SUM(CASE WHEN rating=2 THEN 1 ELSE 0) AS rating2,
SUM(CASE WHEN rating=3 THEN 1 ELSE 0) AS rating3,
SUM(CASE WHEN rating=4 THEN 1 ELSE 0) AS rating4
FROM (
SELECT rating, row_number
FROM (
SELECT rating,
#num:=IF(#group:=book_id, #num+1, 1) row_number,
#group:=book_id bi
FROM book_database
ORDER BY book_id, version DESC
) book
HAVING book.row_number = 1
) book
QUERY2
SELECT
SUM(CASE WHEN price <= 1000 THEN 1 ELSE 0) AS cheap,
SUM(CASE WHEN price >1000 THEN 1 ELSE 0) AS costly
FROM (
SELECT price, row_number
FROM (
SELECT price,
#num:=IF(#group:=book_id, #num+1, 1) row_number,
#group:=book_id bi
FROM book_database
ORDER BY book_id, version DESC
) book
HAVING book.row_number = 1
) book
There are multiple screens in my webpage and with multiple queries but most of them work on same logic. Basically I will query on latest version of any book, and hence I use the nested query.
On some occasions I get different results than intended when same queries ran multiple times on same dataset.
Is my query correct?
Is usage of variables causing this issue?
Since multiple queries are ran in parallel (Although in different database connections) usage of variables is the suspect?
Your use of variables is not correct. MySQL does not guarantee the order of evaluation of expressions in a SELECT clause, so you should set all the variables at the same time.
For instance, the first query should look something more like this:
SELECT SUM( rating = 1 ) AS rating1,
SUM( rating = 2 ) AS rating2,
SUM( rating = 3 ) AS rating3,
SUM( rating = 4 ) AS rating4
FROM (SELECT rating, book_id,
(#rn := if(#b = book_id, #rn + 1,
if(#b := book_id, 1, 1)
)
) as rn
FROM (SELECT rating, book_id, version
FROM book_database
ORDER BY book_id, version DESC
) book CROSS JOIN
(SELECT #rn := 0, #b := -1) params
) book
WHERE rn = 1;
The important part is the part that involves the variables. I also simplified some of the other logic.
But, you don't need variables for this:
SELECT SUM( rating = 1 ) AS rating1,
SUM( rating = 2 ) AS rating2,
SUM( rating = 3 ) AS rating3,
SUM( rating = 4 ) AS rating4
FROM book_database b
WHERE b.version = (SELECT MAX(b2.version)
FROM book_database b2
WHERE b2.book_id = b.book_id
);
With an index on book_database(book_id, version), this should be faster than the version using variables.

How to get rank and max score where each user has many scores in Mysql?

I have a Score table that hold user_id,score in MySql . each user has many scores . I want to get best rank of each user ?
I check a lot of solution but all of them work for table that each user has single score .
I tried this but sometimes user by min score got higher rank :
SET #rank= 0;;
SELECT Users.username, score, rank
FROM (
SELECT * , #rank := #rank +1 AS rank
FROM Scores
JOIN (
SELECT userid AS user_id2, MAX( score ) AS max_score
FROM Scores
GROUP BY user_id2
ORDER BY max_score DESC
) AS max_score_table ON max_score = Scores.score
AND Scores.userid = user_id2
) derived_table
join Users On (Users.id=derived_table.user_id2)
ORDER BY rank
LIMIT 0, 100

get top and bottom 25th percentile average

I have a table with list of employees and the number of units that they have sold.
I want to get the top 25 percentile Avg units sold and Bottom 25 percentile Avg units sold.
I have created a representation of my data SLQ Fiddle
I really have no idea how to start on this? All the examples i see are for SQL Server and not MySQL. Here is what i am thinking.
I want 25 percentile and cant limit to 25 items. Basically it would involve:
1) #_of_employees = The number of total employees.
2) #_of_employees_in_25_percentile = #_of_employees*0.25
3) Calculate the sum of the units sold by the top/bottom 25 percentile (limit #_of_employees_in_25_percentile)
4) Divide the sum by #_of_employees_in_25_percentile to get the average.
How can all this be done efficiently in MySQL?
This is a solution that uses a devious trick I learned from this question.
SELECT id, unit_sold, n * 100 / #total AS percentile
FROM (
SELECT id, unit_sold, #total := #total + unit_sold AS n
FROM mydata, (SELECT #total := 0) AS total
ORDER BY unit_sold ASC
) AS t
SQL Fiddle.
What about this?
SELECT
SUM(unit_sold) AS sum_tot, SUM(unit_sold)/count(id) AS average,
SUM(CASE WHEN percentile<25 THEN unit_sold ELSE 0 END) AS sum_top25,
SUM(CASE WHEN percentile<25 THEN 1 ELSE 0 END) AS count_top25,
SUM(CASE WHEN percentile<25 THEN unit_sold ELSE 0 END)/SUM(CASE WHEN percentile<25 THEN 1 ELSE 0 END) AS average_top25,
SUM(CASE WHEN percentile>75 THEN unit_sold ELSE 0 END) AS sum_bottom25,
SUM(CASE WHEN percentile>75 THEN 1 ELSE 0 END) AS count_bottom25,
SUM(CASE WHEN percentile>75 THEN unit_sold ELSE 0 END)/SUM(CASE WHEN percentile>75 THEN 1 ELSE 0 END) AS average_bottom25
FROM
(SELECT
id, unit_sold, c * 100 / #counter AS percentile
FROM
(SELECT
m.*, #counter:=#counter+1 AS c
FROM
(SELECT #counter:=0) AS initvar, mydata AS m
ORDER BY unit_sold desc
) AS t
WHERE
c <= (25/100 * #counter)
OR c >= (75/100 * #counter)
) AS t2
Output:
SUM_TOT AVERAGE SUM_TOP25 COUNT_TOP25 AVERAGE_TOP25 SUM_BOTTOM25 COUNT_BOTTOM25 AVERAGE_BOTTOM25
850 283.3333 500 1 500 350 2 175
See SQL Fiddle.
The idea is to use the MySQL: LIMIT by a percentage of the amount of records? solution to get the percentiles. Based on that (and on pdw answer) we create an output in which we just show the top 25% and bottom 75%.
Finally, we count and sum to get the values you requested.
Note this runs on top of the command:
SELECT
id, unit_sold, c * 100 / #counter AS percentile
FROM
(SELECT
m.*, #counter:=#counter+1 AS c
FROM
(SELECT #counter:=0) AS initvar, mydata AS m
ORDER BY unit_sold desc
) AS t
WHERE
c <= (25/100 * #counter)
OR c >= (75/100 * #counter)
Whose output is:
ID UNIT_SOLD PERCENTILE
d 500 20
a 250 80
e 100 100
How about going with this logic:
Select all, order by percentile (DESC), limit to 25
Select all, order by percentile (ASC), limit to 25
Is this the type of logic you're looking for ?
Sample queries:
$q1 = mysql_query(SELECT * FROM table_name ORDER BY percentile DESC LIMIT 25)
$q2 = mysql_query(SELECT * FROM table_name ORDER BY percentile ASC LIMIT 25)

count consecutive number of 10 days when number is = 0 or > 10

Here is sqlfiddle that i made with mysql query
http://sqlfiddle.com/#!2/f2794/4
It count 10 consecutive days when present = 0, but i need to add second condition to count where present is > 10.
For example
11
22
0
0
0
0
0
0
0
0
0
0
0
0
1
should count 14
here is that query
select sum(count) total from (
SELECT COUNT(present) as count FROM (
SELECT
IF((q.present != 0), #rownum:=#rownum+1, #rownum:=#rownum) AS rownumber, #prevDate:=q.date, q.*
FROM (
SELECT
name
, date
, present
FROM
teacher, (SELECT #rownum:=0, #prevDate:='') vars
WHERE date BETWEEN '2013-07-01' AND '2013-07-31'
ORDER BY date, present
) q
) sq
GROUP BY present, rownumber
HAVING COUNT(*) >= 10
) d
So if U can help me, pls do it :)
best regards
m.
I dont really understand your query overly well, but I think simply changing (q.Present != 0) to incorporate the additional test should solve your problem:
SELECT sum(count) total from (
SELECT COUNT(present) as count FROM (
SELECT
IF((q.present != 0 AND q.present <= 10), #rownum:=#rownum+1, #rownum:=#rownum) AS rownumber, #prevDate:=q.date, q.*
FROM (
SELECT
name
, date
, present
FROM
teacher, (SELECT #rownum:=0, #prevDate:='') vars
WHERE date BETWEEN '2013-07-01' AND '2013-07-31'
ORDER BY date, present
) q
) sq
GROUP BY present, rownumber
HAVING COUNT(*) >= 10
) d