how to get count total occurance from different tables in Mysql - php

I have three different tables for 3 different activities. The common field is user_id.
Performance:
id | user_id | date | mark
1 | 123 | xx | 20
2 | 456 | xx | 10
3 | 789 | xx | 5
4 | 123 | xx | 10
5 | 456 | xx | 10
6 | 789 | xx | 5
Internal Activities:
id | user_id | date | mark
1 | 123 | xx | 20
2 | 456 | xx | 10
3 | 789 | xx | 5
4 | 123 | xx | 10
5 | 456 | xx | 10
6 | 789 | xx | 5
Other Activities :
id | user_id | date | mark
1 | 123 | xx | 20
2 | 456 | xx | 10
3 | 789 | xx | 5
4 | 123 | xx | 10
5 | 456 | xx | 10
6 | 789 | xx | 5
How to fetch each user marks in all the 3 tables for and sort it in DESC. result should be like
id | user_id | mark
1 | 123 | 90
2 | 456 | 60
3 | 789 | 30
Thanks in advance

SELECT tmp.ID,tmp.USER_ID,tmp.SUM(mark)
FROM
(select * from Performance
union all
select * from Internal_Activities
union all
select * from Other_Activities
) as tmp
group by tmp.USER_ID
Note :- Why are you keeping 3 separate table with same schema ,cant you make it one ?

Try this:
SELECT p.id, p.user_id, SUM(p.mark) FROM Performance p
LEFT JOIN Internal Activities ia ON p.id=ia.id
LEFT JOIN Other Activities oa ON ia.id=oa.id
GROUP BY p.user_id;

SELECT
p.id
,p.user_id
,#performance:=p.mark AS performance
,#other_activities:=oa.mark AS other_activities
,#internal_activities:=ia.mark AS internal_activities
,#total_mark:=#performance+#other_activities+#internal_activities AS total_mark
FROM
table1 p
LEFT JOIN table2 ia
USING(user_id)
LEFT JOIN table2 oa
USING(user_id)

Related

How to group or marge SQL rows via PHP after query

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

how to fetch sum every row mysql

Hy I have 2 table
1.application
id | name | status
====================
1 | morvick | complete
2 | siti | prosess
3 | boby | complete`
2.application_test
id | application_id | test_id | result
======================================
1 | 1 | 1 | 70
2 | 1 | 2 | 80
3 | 1 | 3 | 90
4 | 2 | 1 | 60
5 | 2 | 2 | 80
6 | 2 | 3 | 70
7 | 3 | 1 | 90
8 | 3 | 2 | 70
9 | 3 | 3 | 60
10| 3 | 4 | 80
my Question is :
==================
1. how I can to get sum(result) on each test_id where status complete
2. how I can to get sum(result) on each test_id where status prosess
for example to be like this :
test_id | SUM(result = complete) | SUM(result = proses) |
1 | 90 | 50
2 | 80 | 40
3 | 90 | 60
4 | 80 | 70
Try below query-
SELECT test_id,
SUM(IF(app.status='complete',apt.result,0)) AS complete_sum,
SUM(IF(app.status='process',apt.result,0)) AS process_sum
FROM application_test AS apt
JOIN application AS app ON app.id=apt.application_id
GROUP BY apt.test_id
You can try two query to get sum of result
SELECT test_id , SUM (result)
FROM application a
JOIN application_test t
ON t.test_id = a.id
WHERE a.status = 'complete'
GROUP BY test_id
SELECT test_id , SUM (result)
FROM application a
JOIN application_test t
ON t.test_id = a.id
WHERE a.status = 'prosess'
GROUP BY test_id
if you want in one query
SELECT test_id,
SUM(IF(a.status='complete',result,0)) Completed ,
SUM(IF(a.status='process',result,0)) Process
FROM application a
JOIN application_test t
ON a.id=t.application_id
GROUP BY t.test_id

mysql sort high score such that player placedin 8th position to show complete 15 results

I'm making a rank based game using unity. But I got stuck in the query for the best match please help me out.
The SQL Query:
SELECT name, high_score, #rn:=#rn+1 as row_num
FROM score, (select #rn:=0) as r
ORDER BY high_score DESC
The SQL Table:
row_number | score | firstname
-------------------------------
1 | 210 | Bill
2 | 431 | Linus
3 | 352 | Rasmus
4 | 173 | Steve
5 | 294 | Ross
6 | 411 | Henry
7 | 313 | Jagannath
8 | 115 | Samit
9 | 217 | Vishal
10 | 419 | Tanuj
11 | 321 | Harshad
12 | 123 | Parag
13 | 225 | Aman
14 | 427 | Amar
15 | 329 | Madhur
16 | 131 | Sachin
I want the result like below:
For name'Ross' i.e on 7th position between high and low scores.
Note: The database has thousands of users but result must be 15.
http://i.stack.imgur.com/CroRd.png
Consider the following. Note, I've used 11 instead of 15 in this example (just because it was easier to test against the sample data set). Also, my core algorithm is slower than yours and it doesn't account for ties - so you may want to switch it for something like yours, which is faster, and does!
DROP TABLE IF EXISTS score;
CREATE TABLE score
(score INT NOT NULL,firstname VARCHAR(20) NOT NULL PRIMARY KEY);
INSERT INTO score VALUES
(210 ,'Bill'),
(431 ,'Linus'),
(352 ,'Rasmus'),
(173 ,'Steve'),
(294 ,'Ross'),
(411 ,'Henry'),
(313 ,'Jagannath'),
(115 ,'Samit'),
(217 ,'Vishal'),
(419 ,'Tanuj'),
(321 ,'Harshad'),
(123 ,'Parag'),
(225 ,'Aman'),
(427 ,'Amar'),
(329 ,'Madhur'),
(131 ,'Sachin');
SELECT score,firstname,rank
FROM
( SELECT b.*
FROM
( SELECT x.*
, COUNT(*) rank
FROM score x
JOIN score y
ON y.score >= x.score
GROUP
BY firstname,score
) a
JOIN
( SELECT x.*
, COUNT(*) rank
FROM score x
JOIN score y
ON y.score >= x.score
GROUP
BY firstname,score
) b
WHERE a.firstname = 'Ross'
AND ABS(b.rank-a.rank) <=15
ORDER
BY ABS(b.rank-a.rank) LIMIT 11
) n
ORDER
BY rank;
+-------+-----------+------+
| score | firstname | rank |
+-------+-----------+------+
| 411 | Henry | 4 |
| 352 | Rasmus | 5 |
| 329 | Madhur | 6 |
| 321 | Harshad | 7 |
| 313 | Jagannath | 8 |
| 294 | Ross | 9 |
| 225 | Aman | 10 |
| 217 | Vishal | 11 |
| 210 | Bill | 12 |
| 173 | Steve | 13 |
| 131 | Sachin | 14 |
+-------+-----------+------+

display 0 to 23 hours table using php or mysql

I have a table in mysql that has time date and in military format ( 2014-01-22 16:10:02 )
caller_data
|ID | caller_id | call_time
| 1 | 123 | 2014-01-22 16:10:02
| 2 | 123 | 2014-01-22 16:30:02
| 3 | 123 | 2014-01-22 17:10:02
| 4 | 123 | 2014-01-22 18:05:45
on the range of their time like 16:10 and 16:30 . I group them using HOUR(), the result is 16. I will count it of how many times did the caller call on the range of that hour. so that would be 2.
My query:
SELECT caller_id,
HOUR(str_to_date(date_stamp, "%Y-%m-%d %H:%i:%s")) as hourly,
count(*) as total
from caller_data
group by hourly
order by hourly;
which the result should be:
caller_id | hourly | total
123 | 16 | 2
123 | 17 | 1
123 | 18 | 1
I want to display these 3 rows on a 0-23 . I've been trying to display this with php but it display 3 times when I created a for $i <= 23 ..
for($i=0;i<=23;$i++)
{
foreach ($rec as $row):
echo $row['hourly'];
echo $row['caller_id'];
echo $row['total'];
endforeach;
}
I dont know if it's possible to display this on mysql.. can someone show how to do it with php or mysql?
| hours | caller_id | total
| 0 | 123 | 0
| 1 | 123 | 0
| 2 | 123 | 0
| 3 | 123 | 0
| 4 | 123 | 0
| 5 | 123 | 0
| 6 | 123 | 0
| 7 | 123 | 0
| 8 | 123 | 0
| 9 | 123 | 0
| 10 | 123 | 0
| 11 | 123 | 0
| 12 | 123 | 0
| 13 | 123 | 0
| 14 | 123 | 0
| 15 | 123 | 0
| 16 | 123 | 2
| 17 | 123 | 1
| 18 | 123 | 1
| 19 | 123 | 0
| 20 | 123 | 0
| 21 | 123 | 0
| 22 | 123 | 0
| 23 | 123 | 0
You can do this in SQL with a left outer join. You just have to type in all the hours:
select caller_id, n.n as hourly, coalesce(total, 0) as total
from (select 1 as n union all select 2 union all select 3 union all select 4 union all
select 5 union all select 6 union all select 7 union all select 8 union all
select 9 union all select 10 union all select 11 union all select 12 union all
select 13 union all select 14 union all select 15 union all select 16 union all
select 17 union all select 18 union all select 19 union all select 20 union all
select 21 union all select 22 union all select 23 union all select 24
) n left outer join
(select caller_id, HOUR(str_to_date(date_stamp, "%Y-%m-%d %H:%i:%s")) as hourly,
count(*) as total
from caller_data
group by hourly
) rep
on n.n = rep.hourly
order by hourly;

Selecting random triplicates (or more) from database

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

Categories