I have a MySQL table like bellow
id | roll | exam_id | course_id | marks | status
----------------------------------------------------------
1 | 01001 | 1 | 1 | 56 | 1
2 | 01002 | 1 | 1 | 68 | 1
3 | 01003 | 1 | 1 | 55 | 1
4 | 01004 | 1 | 1 | 67 | 1
5 | 01001 | 1 | 2 | 54 | 1
6 | 01002 | 1 | 2 | 59 | 1
7 | 01003 | 1 | 2 | 62 | 1
8 | 01004 | 1 | 2 | 63 | 1
9 | 01001 | 2 | 3 | 61 | 1
10 | 01002 | 2 | 3 | 48 | 1
11 | 01003 | 2 | 3 | 22 | 1
12 | 01004 | 2 | 3 | 39 | 1
Now I want to have all the row with exam_id = 1
SELECT * FROM result WHERE exam_id=1 ORDER BY course_id
After that I need to display this table inside HTML after grouping it by roll means one row for each roll that have row-span according to the course number of the result table
Roll | course_id | marks
-----------------------------
01001 | 1 | 56
| 2 | 68
-----------------------------
01002 | 1 | 55
| 2 | 67
-----------------------------
01003 | 1 | 55
| 2 | 62
-----------------------------
01004 | 1 | 67
| 2 | 63
I'm using Codeigniter framework to doing this project. Any suggestions about how I can I do this?
Thank you in advance.
[EDIT]
Current SQL I'm using to do this:
SELECT * FROM `exam_result` JOIN `course` ON `course`.`course_tab_id`=`exam_result`.`result_course` WHERE `exam_id` = '1' AND `result_status` = 1 GROUP BY `exam_result`.`exam_roll`, `course`.`course_tab_id` ORDER BY `exam_result`.`exam_roll` ASC, `course`.`course_id` ASC
Try this but the difference in this table on my first query is that the course title will be included on a single table, I have set the marks as AVG due to so if ever you have duplicate data you will see their average result for the course and roll of a school or whatever you use this structure for
SELECT roll, exam_id, a.course_id, marks, status, course_title, course_credit
FROM
(SELECT roll, exam_id, course_id, AVE(marks) as marks, status FROM result) as a
LEFT JOIN
(SELECT course_id, course_title, course_credit FROM course) as b
ON
a.course_id = b.course_id
WHERE exam_id = '1' -- you can remove this if you wanted all exam appear on your list
GROUP BY roll, exam_id, a.course_id, marks, status, course_title, course_credit
ORDER BY roll, course_id, marks
Try this sql query
SELECT Roll, course_id, AVG(marks)
FROM result WHERE exam='1'
GROUP BY Roll, course_id
ORDER BY roll, course_id, marks
Related
Hello can you help me get the rank with custom ties?
i have a table of Scores stores all the scores given by the judges.
+----+----------+-------------+--------+
| Id | judge_id |performer_id | score |
+----+----------+-------------+--------+
| 1 | 1 | 1 | 98 |
| 2 | 1 | 2 | 98 |
| 3 | 1 | 3 | 94 |
| 4 | 1 | 4 | 96 |
| 5 | 2 | 1 | 93 |
| 6 | 2 | 2 | 80 |
+----+----------+-------------+--------+
heres what the code i have searched.
SELECT
id
, judge_id
, performer_id
, score
, FIND_IN_SET(
score
, (SELECT
GROUP_CONCAT(DISTINCT score ORDER BY score DESC)
FROM
scores
WHERE
judge_id = 1
)
) AS rank
FROM
scores
WHERE
judge_id = 1
ORDER BY rank ASC
and the output of this is:
+----+----------+-------------+--------+------+
| Id | judge_id |performer_id | score | rank |
+----+----------+-------------+--------+------+
| 1 | 1 | 1 | 98 | 1 |
| 2 | 1 | 2 | 98 | 1 |
| 3 | 1 | 4 | 96 | 3 |
| 4 | 1 | 3 | 94 | 4 |
+----+----------+-------------+--------+------+
it is working but the output is not what i want.
i want to get the ranking and ties like this.
+----+----------+-------------+--------+------+
| Id | judge_id |performer_id | score | rank |
+----+----------+-------------+--------+------+
| 1 | 1 | 1 | 98 | 1.5 |
| 2 | 1 | 2 | 98 | 1.5 |
| 3 | 1 | 4 | 96 | 3 |
| 4 | 1 | 3 | 94 | 4 |
+----+----------+-------------+--------+------+
where get all the rank of the tie then divide it by how many performer ties in the rank.
ex.
performer 1 score 98 rank 1
performer 2 score 98 rank 1
suppose that performer 2 should get rank 2
i want to compute it like
1+2 = 3 then divide it by 2 since 2 performers are tie in rank 1
1=2 = 3 / 2
answer is 1.5
im sorry for my english
but please can any one help me? im stuck at this problem.
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(performer_id SERIAL PRIMARY KEY
,score INT NOT NULL
);
INSERT INTO my_table VALUES
(1,98),
(2,98),
(3,94),
(4,96);
SELECT x.*
, y.rank
FROM my_table x
JOIN
( SELECT score
, SUM(i)/COUNT(*) rank
FROM
( SELECT score
, #i:=#i+1 i
FROM my_table x
ORDER
BY score DESC
, performer_id
) a
JOIN
( SELECT #i:=0 ) vars
GROUP
BY score
) y
ON y.score = x.score;
+--------------+-------+--------+
| performer_id | score | rank |
+--------------+-------+--------+
| 1 | 98 | 1.5000 |
| 2 | 98 | 1.5000 |
| 3 | 94 | 4.0000 |
| 4 | 96 | 3.0000 |
+--------------+-------+--------+
Note: For newer versions of MySQL, you would use Windowing functions/CTE (I'm not really sure of the correct terminology). I've written this for older versions, although MySQL can have issues when initializing variables this way. If that's a problem, here's another (slightly 'hackier' - and theoretically incorrect, but practically fine) way of initialising the variable...
SELECT x.*
, y.rank
FROM my_table x
JOIN
( SELECT score
, SUM(i)/COUNT(*) rank
FROM
( SELECT score
, #j:=#j+1 i
FROM my_table x
JOIN ( SELECT #j:=0 ) vars
ORDER
BY score DESC
, performer_id
) a
GROUP
BY score
) y
ON y.score = x.score;
+--------------+-------+------+
| performer_id | score | rank |
+--------------+-------+------+
| 1 | 98 | 1.5 |
| 2 | 98 | 1.5 |
| 3 | 94 | 4 |
| 4 | 96 | 3 |
+--------------+-------+------+
I am using the query to find the rank of a user in a given test id, and this gives me rank for just one test at a time and I have to use foreach to get the test rank of all the test.
SELECT * , t.UserRank
FROM (
SELECT * , (
#rownum := #rownum +1
)UserRank
FROM User_Date_Table, (
SELECT #rownum :=0
)t
WHERE my_test_id = '$test_id'
ORDER BY test_score DESC
)t
WHERE user_id = '$my_user_id'
Can a query be generated which can give me user rank for all the test taken by user in single query as this will reduced the db hitting multiple times.
I have to find the all the ranks of user with Test_Type_Id = $my_test_type_id(say), joining a.id with b.my_test_id for a user with user_id = $my_user_id(say)
TABLE STRUCTURE
My_Test_Table (a)
id | name | Test_Type_Id
----------------------------------------------
1 | name_1 | 1
2 | name_2 | 1
3 | name_3 | 2
4 | name_4 | 1
5 | name_5 | 1
6 | name_6 | 2
7 | name_7 | 1
8 | name_8 | 2
9 | name_9 | 1
User_Date_Table (b)
id | my_test_id | user_id | test_score
---------------------------------------------------------
1 | 1 | 32 | 34
2 | 1 | 2 | 345
3 | 2 | 4 | 654
4 | 1 | 76 | 87
5 | 3 | 23 | 453
6 | 2 | 5 | 45
7 | 1 | 43 | 22
8 | 2 | 7 | 987
9 | 2 | 32 | 45
10 | 1 | 1 | 12
11 | 1 | 9 | 35
12 | 3 | 67 | 765
13 | 1 | 88 | 23
14 | 2 | 34 | 76
15 | 3 | 1 | 765
16 | 2 | 54 | 45
17 | 1 | 10 | 87
18 | 1 | 23 | 3
19 | 3 | 44 | 345
20 | 1 | 55 | 232
21 | 2 | 28 | 234
22 | 3 | 32 | 231
Simplest is probably to just remove the user variable for ranking and just do it using a subquery;
SELECT *, (SELECT COUNT(*)+1
FROM User_Date_Table b
WHERE a.my_test_id = b.my_test_id
AND a.test_score < b.test_score) userrank
FROM User_Date_Table a
WHERE user_id = '1';
An SQLfiddle to test with.
SELECT * , t.UserRank
FROM (
SELECT * , #rownum :=if(#user!=user_id,0, #rownum +1),#user:=user_id UserRank
FROM User_Date_Table , (SELECT #rownum :=0,#user :=-1) t
ORDER BY my_test_id ,test_score DESC
)t
WHERE user_id = '$my_user_id'
We introducean additional variable #user to reset #rownum on user_id change
I have two tables:
Students Student_Grades
V------------------------V
+----+------+ +----+------------+---------+-------+
| id | name | | id | student_id | subject | grade |
+----+------+ +----+------------+---------+-------+
| 0 | Dave | | 0 | 0 | Math | 100 |
+----+------+ +----+------------+---------+-------+
| 1 | John | | 1 | 0 | Chem | 90 |
+----+------+ +----+------------+---------+-------+
| 2 | Kate | | 2 | 0 | CompSCI | 95 |
+----+------+ +----+------------+---------+-------+
| 3 | Mimi | | 3 | 1 | ELA | 98 |
+----+------+ +----+------------+---------+-------+
| 4 | 2 | Biology | 92 |
+----+------------+---------+-------+
| 5 | 2 | Chem | 94 |
+----+------------+---------+-------+
| 6 | 2 | Math | 98 |
+----+------------+---------+-------+
| 7 | 3 | Math | 100 |
+----+------------+---------+-------+
I would like to select all subjects and grades from a random student that is enrolled in more than three subjects. (Either Dave or Kate)
Students John and Mimi would not be even considered because they are not enrolled in three subjects.
I know I can achieve this with PHP but I would like this to be done with one query to the database.
SELECT * FROM Students t JOIN (SELECT CEIL(MAX(ID)*RAND()) AS ID FROM Students) AS x ON t.ID >= x.ID LIMIT 1
With the above query, I have selected a random student, with that I can go in and check if they have three subjects with SELECT count(subjects) FROM Students WHERE id=random_id.
If the count returned is below three, then I throw away the results and run the first query again.
How would I attempt this in one query?
This is tested and working:
SELECT *
FROM Students s
JOIN (
SELECT student_id
FROM Student_Grades
GROUP BY student_id
HAVING COUNT(*) >= 3
ORDER BY RAND()
LIMIT 1
) rs
ON rs.student_id = s.id
JOIN
Student_Grades sg
ON sg.student_id = s.id
Here's the SQL Fiddle: http://sqlfiddle.com/#!2/e5b5b/1
i have this table called bag:
+--------+----------+---------+----------+
| bag_id | chara_id | item_id | item_qty |
+--------+----------+---------+----------+
| 1 | 1 | 2 | 22 |
| 2 | 1 | 1 | 55 |
| 3 | 3 | 1 | 2 |
| 6 | 3 | 4 | 2 |
| 7 | 4 | 4 | 2 |
| 8 | 5 | 4 | 2 |
| 9 | 6 | 4 | 2 |
| 10 | 1 | 5 | 1 |
| 11 | 1 | 2 | 1 |
| 12 | 1 | 2 | 1 |
| 13 | 1 | 2 | 1 |
| 14 | 1 | 8 | 1 |
| 15 | 1 | 6 | 1 |
| 16 | 1 | 8 | 1 |
| 17 | 1 | 6 | 1 |
+--------+----------+---------+----------+
the relationship goes as 1 chara = many item
now i dont want 1 chara = many duplicated item.
how can i make a query that delete's the duplicated values?
like chara_id: 1 has 3 duplicated item_id: 2
i want to delete the other 2.
Not the best way to do it. But the below should definetly work:
Delete from Bag
where bag_id
not in (
select min(bag_id) from bag a,
(select chara_id, item_id
from bag group by chara_id, item_id
having count(*) > 1) b
where a.chara_id = b.chara_id and a.item_id = b.item_id
UNION
select bag_id from bag a,
(select chara_id, item_id
from bag group by chara_id, item_id
having count(*) = 1) b
where a.chara_id = b.chara_id and a.item_id = b.item_id
)
You can simply join table bag with a subquery which gets the minimum bag_id for every combination of chara_ID and item_ID. Records that have null values on any fields on the subquery are the records that will be deleted.
DELETE a
FROM bag a
LEFT JOIN
(
SELECT chara_ID, item_ID, MIN(bag_ID) min_ID
FROM bag
GROUP BY chara_ID, item_ID
) b ON a.bag_ID = b.min_ID AND
a.chara_ID = b.chara_ID AND
a.item_ID = b.item_ID
WHERE b.min_ID IS NULL
SQLFiddle Demo
I have 2 MySQL tables, one of which has a numeric column to orgainise the order I need the items to be displayed:
item_names
menu_id | dish_id | section_id | item_name
--------------------------------------------------
1 | 23 | 2 | Pie
1 | 24 | 2 | Fish
1 | 25 | 3 | Apples
1 | 26 | 2 | Onions
1 | 27 | 2 | Chips
link_extras
extra_id | dish_id | sort
-----------------------------
1 | 23 | 2
2 | 23 | 2
3 | 23 | 2
1 | 24 | 0
5 | 24 | 0
6 | 26 | 3
12 | 26 | 3
1 | 27 | 1
1 | 25 | 0
Basically what I am trying to do is extract each dish with a certain menu_id and section_id from the table item_names and order the output in respect to the sort column in the link_extras table.
so far:
$query="SELECT a.item_name, a.dish_id, b.sort
FROM item_names AS a, link_extras AS b
WHERE a.menu_id='1'
AND a.section_id='2'
AND b.dish_id=a.dish_id
GROUP BY b.dish_id
ORDER BY b.sort";
I am quite new to databases so would appreciate any help. The result I am after is
Fish
Chips
Pie
Onions
Unfortunately just can't get the order correct.
You need to use a simple JOIN
SELECT a.item_name, a.dish_id, b.sort
FROM item_names AS a
JOIN link_extras AS b
ON a.dish_id = b.dish_id
WHERE menu_id = 1
AND section_id = 2
GROUP BY b.dish_id
ORDER BY b.sort
Output:
| ITEM_NAME | DISH_ID | SORT |
------------------------------
| Fish | 24 | 0 |
| Chips | 27 | 1 |
| Pie | 23 | 2 |
| Onions | 26 | 3 |
See this SQLFiddle
SELECT
in.item_name
FROM item_names AS in
LEFT JOIN link_extras AS le
ON le.dish_id = in.dish_id
WHERE in.menu_id = 1
AND in.section_id = 2
ORDER BY le.sort
Demo Here
Output
| ITEM_NAME |
-------------
| Fish |
| Chips |
| Pie |
| Onions |