SQL Query to retrieve below average score - mysql

Hello I'm working on a system for primary school and im stuck on queries in database part. I would like to retrieve:
Number of students below the average score
Average mark for each student across all tests
Average mark for each test
I'm not really good at queries and I couldn't work it out. I appreciate any help. Thanks
Below you can find my tables and test data
Tables:
CREATE TABLE Student
(
StudentID INT auto_increment,
ClassID VARCHAR(10),
FirstName VARCHAR(25),
LastName VARCHAR(25),
DateOfBirth DATE,
Gender VARCHAR(10),
PRIMARY KEY (StudentID, ClassID)
);
create table Subjects
(
SubjectID INT,
SubjectName VARCHAR(25),
PRIMARY KEY (SubjectID)
);
create table Grade
(
StudentID INT,
SubjectID INT,
ClassID VARCHAR(10),
Grade DECIMAL(5,1),
FOREIGN KEY (StudentID) REFERENCES Student(StudentID),
FOREIGN KEY (SubjectID) REFERENCES Subjects(SubjectID),
FOREIGN KEY (ClassID) REFERENCES Student(ClassID)
);
Test data:
INSERT INTO Student (StudentID, ClassID, FirstName, LastName, DateOfBirth, Gender)
VALUES ('', '01', 'John', 'Smith', '15/01/2000', 'Male'),
('', '01', 'Michael', 'Black', '15/03/2000', 'Male'),
('', '01', 'Dennis', 'White', '07/08/1999', 'Male'),
('', '01', 'Emy', 'Blue', '10/04/2000', 'Female'),
('', '01', 'Joe', 'Yellow', '09/05/2000', 'Male'),
('', '01', 'Aaren', 'Jackson', '09/009/1999', 'Male'),
('', '01', 'Marta', 'Harris', '30/01/2000', 'Female'),
('', '01', 'Laura', 'Lewis', '09/01/2000', 'Female'),
('', '01', 'Michael', 'Jackson', '01/01/2000', 'Male'),
('', '02', 'Piotr', 'Kowalski', '15/01/2000', 'Male'),
('', '02', 'Harris', 'Bialy', '15/03/2000', 'Male'),
('', '02', 'Porter', 'Czarny', '07/08/1999', 'Male'),
('', '02', 'Maciek', 'Blue', '10/04/2000', 'Female'),
('', '02', 'Mateusz', 'Yellow', '09/05/2000', 'Male'),
('', '02', 'Aaren', 'Jackson', '09/009/1999', 'Male'),
('', '02', 'Marta', 'Harris', '30/01/2000', 'Female'),
('', '02', 'Laura', 'Lewis', '09/01/2000', 'Female'),
('', '02', 'Chaytan', 'Jackson', '01/01/2000', 'Male');
INSERT INTO Subjects (SubjectID, SubjectName)
VALUES ('01', 'English'),
('02', 'Mathematics'),
('03', 'Science'),
('04', 'Geography'),
('05', 'IT'),
('06', 'History');
INSERT INTO Grade (StudentID, SubjectID, ClassID, Grade)
VALUES ('1', '2', '01', '60.5'),
('2', '2', '01', '70.0'),
('3', '2', '01', '40.0'),
('4', '2', '01', '33.5'),
('5', '2', '01', '90.0'),
('6', '2', '01', '77.5'),
('7', '2', '01', '89.0'),
('8', '2', '01', '74.0'),
('9', '2', '01', '66.5'),
('10', '2', '02', '30.5'),
('11', '2', '02', '50.0'),
('12', '2', '02', '30.0'),
('13', '2', '02', '73.5'),
('14', '2', '02', '70.0'),
('15', '2', '02', '57.5'),
('16', '2', '02', '69.0'),
('17', '2', '02', '34.0'),
('18', '2', '02', '76.5'),
('1', '1', '01', '65.5'),
('2', '1', '01', '73.0'),
('3', '1', '01', '41.0'),
('4', '1', '01', '39.5'),
('5', '1', '01', '96.0'),
('6', '1', '01', '70.5'),
('7', '1', '01', '80.0'),
('8', '1', '01', '74.0'),
('9', '1', '01', '64.5'),
('10', '1', '02', '55.5'),
('11', '1', '02', '43.0'),
('12', '1', '02', '61.0'),
('13', '1', '02', '49.5'),
('14', '1', '02', '76.0'),
('15', '1', '02', '80.5'),
('16', '1', '02', '99.0'),
('17', '1', '02', '100.0'),
('18', '1', '02', '55.5');

Here you go, you have all your homework in one fiddle send it to your teacher :D fiddle
SELECT Student.StudentID, Student.FirstName, Student.LastName, Grade.Grade, Subjects.SubjectName
FROM Student INNER JOIN Grade ON Grade.StudentID=Student.StudentID
INNER JOIN Subjects ON Grade.SubjectID=Subjects.SubjectID
WHERE Grade.Grade<50;
SELECT Student.StudentID, Student.FirstName, Student.LastName, AVG(Grade.Grade) AS Average
FROM Student INNER JOIN Grade ON Grade.StudentID=Student.StudentID
GROUP BY Grade.StudentID;
SELECT Subjects.SubjectID, Subjects.SubjectName, AVG(Grade.Grade) AS Average
FROM Subjects INNER JOIN Grade ON Grade.SubjectID=Subjects.SubjectID
GROUP BY Grade.SubjectID;

Here would be my first tries :
SELECT COUNT(*) FROM Grade WHERE Grade <= AVG(Grade);
SELECT AVG(Grade) FROM Grade GROUP BY StudentID;
SELECT AVG(Grade) FROM Grade GROUP BY SubjectID;
Some adaptations to your specific case might be necessary. By the way, next time your use Stack Overflow, post your attempts. Efforts are greatly appreciated here, and will help you improve beyond this particular case. Plus, copy/paste won't make you capable after graduation.
About GROUP BY : https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html, and AVG : http://www.tutorialspoint.com/mysql/mysql-avg-function.htm.

Related

Find records where condition met x number of times in mysql/sql

I'm struggling with what is a complicated SQL query for me, although I believe that it is not particularly complicated. I'm close to the right answer, but not quite there yet.
My database represents a criminal abstract. I have three tables in my database (I've simplified my schema enormously for the purposes of this question): arrest, arrestcharges, and dispositions.
Each defendant can have multiple arrests (defendant table not included for simplification). Each arrest can have multiple charges, which are in the arrestcharges table. And each charge has a grade and is associated with a disposition (guilty, not guilty, etc...). The dispositions are categorized so that 0=some form of guilt disposition, 1=a non-guilty disposition.
I want to find individuals who have been convicted of a charge graded as "M1" on more than one case. If an individual has been convicted of more than M1, but they are in the same case, that person shouldn't be returned (unless they have another case with an M1 conviction).
A sqlfiddle link and the SQL to create and populate the table is below.
I believe that this query should work, but it doesn't:
select a.defendantid, count(a.id)
FROM `arrest` AS a LEFT JOIN `arrestcharges` AS ac
ON a.id=ac.arrestid LEFT JOIN `dispositions` AS d
ON ac.dispositionid=d.id
WHERE d.dispocategory=0 AND ac.grade="M1"
GROUP BY a.id HAVING COUNT(a.id) > 1 ORDER BY a.defendantid;
Based on the sql below, I expect that defendant IDs 1 and 5 should be returned since they are the only two defendants with an M1 conviction in more than one arrest. But the actual response I am getting is 2 and 5. 2 should not be returned b/c defendant 2 only has one arrest in the database.
Any thoughts on what I am doing wrong?
SQLFiddle
CREATE TABLE IF NOT EXISTS `arrest` (
`id` int(6) unsigned NOT NULL,
`defendantid` int(6) unsigned NOT NULL,
`docketno` varchar(21) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `arrestcharges` (
`id` int(6) unsigned NOT NULL,
`arrestid` int(6) unsigned NOT NULL,
`grade` varchar(2) NOT NULL,
`dispositionid` int(6) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `dispositions` (
`id` int(6) unsigned NOT NULL,
`disposition` varchar(30) NOT NULL,
`dispoCategory` int(1) unsigned NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `arrest` (`id`, `defendantid`, `docketno`) VALUES
('1', '1', 'MC-51-CR-0000222-1999'),
('2', '1', 'MC-51-CR-0000223-1999'),
('3', '1', 'MC-51-CR-0000224-1999'),
('4', '2', 'MC-51-CR-0002343-2000'),
('5', '3', 'MC-51-CR-0002349-2000'),
('6', '3', 'MC-51-CR-0002350-2000'),
('7', '3', 'MC-51-CR-0002351-2010'),
('8', '3', 'MC-51-CR-0002352-2013'),
('9', '4', 'MC-51-CR-1209293-2011'),
('10', '5', 'MC-51-CR-2389848-1999'),
('11', '5', 'MC-51-CR-3893923-1999'),
('12', '5', 'MC-51-CR-2393912-1999');
INSERT INTO `dispositions` (`id`, `disposition`, `dispoCategory`) VALUES
('1', 'Guilty', '0'),
('2', 'Not Guilty', '1'),
('3', 'Guilty Plea', '0'),
('4', 'Dismissed', '1');
INSERT INTO `arrestcharges` (`id`, `arrestid`, `grade`, `dispositionid`) VALUES
('1', '1', 'M1', '1'),
('2', '1', 'M', '2'),
('3', '2', 'F', '2'),
('4', '2', 'M1', '3'),
('5', '3', 'M1', '1'),
('6', '4', 'M2', '4'),
('7', '4', 'M1', '3'),
('8', '4', 'M1', '3'),
('9', '4', 'M1', '1'),
('10', '5', 'M1', '2'),
('11', '6', 'M1', '2'),
('12', '7', 'F2', '1'),
('13', '8', 'F3', '1'),
('14', '9', 'M1', '2'),
('15', '9', 'M1', '2'),
('16', '9', 'M1', '2'),
('17', '9', 'M1', '2'),
('18', '10', 'M1', '1'),
('19', '10', 'M1', '1'),
('20', '11', 'M2', '3'),
('21', '12', 'M1', '4'),
('22', '12', 'M1', '3');
Try this query:
select a.defendantid, count(distinct(ac.arrestid)) as count
FROM `arrest` AS a LEFT JOIN `arrestcharges` AS ac
ON a.id=ac.arrestid LEFT JOIN `dispositions` AS d
ON ac.dispositionid=d.id
WHERE d.dispocategory=0 AND ac.grade="M1"
GROUP BY a.defendantid HAVING count>1;
You should count the distinct number as distinct_count of rows you need and make use of having filter such as having distinct_count>1. This way you can ensure that the count are not getting repeated.
You appear to be aggregating by the wrong column. You need a.defendantid in the group by:
SELECT a.defendantid, count(*)
FROM `arrest` a JOIN
`arrestcharges` ac
ON a.id = ac.arrestid JOIN
`dispositions` d
ON ac.dispositionid = d.id
WHERE d.dispocategory = 0 AND ac.grade = 'M1'
GROUP BY a.defendantid
HAVING COUNT(DISTINCT a.id) > 1
ORDER BY a.defendantid;
Note that I also changed the outer joins to inner joins. If charges and dispositions are not available, then your filtering conditions cannot be met. Hence, the appropriate join is an inner join.

mysql cant' get null data to show up in query

Here is what I need to achieve:
person_id last_name first_name region_id region name
1 barnum phineas 1 maricopa
2 loman willy 2 pima
2 loman willy 3 pinal
2 loman willy 4 santa cruz
3 kay mary 5 cochise
3 kay mary 6 gila
3 kay mary 7 graham
4 lillian vernon NULL NULL
Here are my tables:
Create database sales
use sales
create table if not exists
`Sales_People`
(`person_id` int primary key,
`last_name` char(16) not null,
`first_name` char(16) not null);
INSERT INTO Sales_people
(`person_id`, `last_name`, `first_name`)
values
('1', 'barnum', 'phineas'),
('2', 'loman', 'willy'),
('3', 'kay', 'mary'),
('4', 'lillian', 'vernon');
create table if not exists
`Sales_Region`
(`region_id` int primary key,
`name` char(16) not null);
INSERT INTO Sales_Region
(`region_id`, `name`)
Values
('1', 'maricopa'),
('2', 'pima'),
('3', 'pinal'),
('4', 'santa cruz'),
('5', 'cochise'),
('6', 'gila'),
('7', 'graham');
create table if not exists
`Sales_People_Region`
(`person_id` int not null,
`region_id` int not null,
constraint spr_pk primary key(person_id, region_id),
constraint spr_fk1 foreign key(person_id)
references Sales_People(person_id),
constraint spr_fk2 foreign key(region_id)
references Sales_Region(region_id));
INSERT INTO Sales_People_Region
(`person_id`, `region_id`)
Values
('1', '1'),
('2', '2'),
('2','3'),
('2', '4'),
('3', '5'),
('3', '6'),
('3','7');
create table if not exists
`Sales`
(`year` int not null,
`month` int not null,
`region_id` int not null,
`amount_sold` decimal(11,2),
constraint s_pk primary key(year, month, region_id),
constraint s_fk foreign key(region_id)
references Sales_Region(region_id));
INSERT INTO Sales
(`year`, `month`, `region_id`, `amount_sold`)
Values
('2016', '01', '1', '800000'),
('2016', '02', '1', '850000'),
('2016', '03', '1', '990000'),
('2016', '01', '2', '425000'),
('2016', '02', '2', '440000'),
('2016', '03', '2', '450000'),
('2016', '01', '3', '200000'),
('2016', '02', '3', '210000'),
('2016', '03', '3', '220000'),
('2016', '01', '4', '50000'),
('2016','02', '4', '52000'),
('2016', '03', '4', '55000'),
('2016', '01', '5', '40000'),
('2016', '02', '5', '41000'),
('2016', '03', '5', '42000'),
('2016', '01', '6', '3000'),
('2016', '02', '6', '31000'),
('2016','03', '6', '32000'),
('2016', '01', '7', '20000'),
('2016', '02', '7', '21000'),
('2016', '03', '7', '22000');
here is my code:
select sales_people.person_id, `last_name`, `first_name`, sales_region.Region_id,
trim(sales_region.`name`) AS 'Region Name'
from `sales_region`
inner join sales_people_region
on sales_people_region.region_id = sales_region.region_id
inner join sales_people
on sales_people_region.`person_id` = sales_people.`person_id`
group by sales_region.region_id, sales_people.person_id
having sales_people.person_id >= ''
order by sales_people.person_id, sales_region.region_id asc;
what I get:
person_id last_name first_name Region_id "Region Name"
1 barnum phineas 1 maricopa
2 loman willy 2 pima
2 loman willy 3 pinal
2 loman willy 4 "santa cruz"
3 kay mary 5 cochise
3 kay mary 6 gila
3 kay mary 7 graham
I can't get it to let me see the last person_id because they have no region_ids assigned to them. In the table sales_people_region region_id is a primary key and therefore not able to be null.
If I query sales_people and group by person_id she does come up.
I think an outer join would remedy this. An inner join requires there to be at least one row extant on each side of the join; a left outer join will select all rows from the left-hand table including those for which there is no matching row in the right-hand table. (A right outer join is the mirror image of this, and a full outer join selects unmatched rows from both sides.)
Try this query:
SELECT sales_people.person_id, last_name, first_name, sales_region.Region_id,
TRIM(sales_region.`name`) AS 'Region Name'
FROM sales_people
LEFT OUTER JOIN sales_people_region
on sales_people.person_id = sales_people_region.person_id
LEFT OUTER JOIN sales_region
ON sales_people_region.region_id = sales_region.region_id
GROUP BY sales_region.region_id, sales_people.person_id
HAVING sales_people.person_id != ''
ORDER BY sales_people.person_id, sales_region.region_id ASC;

MySQL - Calculate percentage and count number of related records

Please need help to complete the code to do the followin:
Calculate the number of votes and percentages of specific records, is a site of movies, where users can view and vote movies, then the website should show all films more to lower the number of votes by users, here the details of what I'm trying to do.
1) Calculate the number of votes in general each film.
2) Get the number of votes by separate "They are altogether 3 table[votes]" for each movie, such as:
Movie 1 There have been a total of 100 votes, 20% of users seemed Regular, 30% of users seemed Good and 50% of users seemed Very good.
3) Get the percentage of the maximum number of votes between "3 of table [votes]", if users voted more for the film was very good, I have to calculate the percentage of that, so we can create a small donut or graphic, showing movies and casts more than you liked to users, for example:
The film was voted Movie 1, with a total of 450 votes, which accounts for 50% of all votes received by user rating.
So far I have done this:
SELECT
M.name AS title_movie,
M.year AS premiere,
G.name AS gender,
COUNT(MHR.vote_id) AS total_voting_movie
FROM movies M
LEFT JOIN gender G ON M.gender_id = G.id
LEFT JOIN movies_has_rating MHR ON M.id = MHR.movie_id
GROUP BY M.id
ORDER BY M.id DESC
Graphic tables database:
The complete code for the entire database:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for gender
-- ----------------------------
DROP TABLE IF EXISTS `gender`;
CREATE TABLE `gender` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of gender
-- ----------------------------
INSERT INTO `gender` VALUES ('1', 'Action');
INSERT INTO `gender` VALUES ('2', 'Musical');
INSERT INTO `gender` VALUES ('3', 'Sci Fi');
-- ----------------------------
-- Table structure for movies
-- ----------------------------
DROP TABLE IF EXISTS `movies`;
CREATE TABLE `movies` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`year` varchar(255) DEFAULT NULL,
`gender_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of movies
-- ----------------------------
INSERT INTO `movies` VALUES ('1', 'Alien', '1979', '1');
INSERT INTO `movies` VALUES ('2', 'Aliens', '1986', '1');
INSERT INTO `movies` VALUES ('3', 'Moulin Rouge', '2001', '3');
INSERT INTO `movies` VALUES ('4', 'Guys and Dolls', '1955', '3');
INSERT INTO `movies` VALUES ('5', 'Mama Mia', '1970', '3');
INSERT INTO `movies` VALUES ('6', 'Starman', '1984', '1');
INSERT INTO `movies` VALUES ('7', 'Tron', '1982', '1');
INSERT INTO `movies` VALUES ('8', 'The Matrix', '1988', '2');
-- ----------------------------
-- Table structure for movies_has_rating
-- ----------------------------
DROP TABLE IF EXISTS `movies_has_rating`;
CREATE TABLE `movies_has_rating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`movie_id` int(11) NOT NULL,
`vote_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=156 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of movies_has_rating
-- ----------------------------
INSERT INTO `movies_has_rating` VALUES ('1', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('2', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('3', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('4', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('5', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('6', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('7', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('8', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('9', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('10', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('11', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('12', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('13', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('14', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('15', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('16', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('17', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('18', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('19', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('20', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('21', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('22', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('23', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('24', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('25', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('26', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('27', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('28', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('29', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('30', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('31', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('32', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('33', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('34', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('35', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('36', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('37', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('38', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('39', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('40', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('41', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('42', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('43', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('44', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('45', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('46', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('47', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('48', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('49', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('50', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('51', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('52', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('53', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('54', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('55', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('56', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('57', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('58', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('59', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('60', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('61', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('62', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('63', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('64', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('65', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('66', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('67', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('68', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('69', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('70', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('71', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('72', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('73', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('74', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('75', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('76', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('77', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('78', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('79', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('80', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('81', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('82', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('83', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('84', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('85', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('86', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('87', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('88', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('89', '3', '2');
INSERT INTO `movies_has_rating` VALUES ('90', '3', '3');
INSERT INTO `movies_has_rating` VALUES ('91', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('92', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('93', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('94', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('95', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('96', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('97', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('98', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('99', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('100', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('101', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('102', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('103', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('104', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('105', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('106', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('107', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('108', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('109', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('110', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('111', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('112', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('113', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('114', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('115', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('116', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('117', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('118', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('119', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('120', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('121', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('122', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('123', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('124', '6', '3');
INSERT INTO `movies_has_rating` VALUES ('125', '6', '3');
INSERT INTO `movies_has_rating` VALUES ('130', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('131', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('132', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('133', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('134', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('135', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('136', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('137', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('138', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('139', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('140', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('141', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('142', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('143', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('144', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('145', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('146', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('147', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('148', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('149', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('150', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('151', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('152', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('153', '8', '3');
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'Name user 1', '1#1.com');
INSERT INTO `users` VALUES ('2', 'Name user 2', '2#2.com');
INSERT INTO `users` VALUES ('3', 'Name user 3', '3#3.com');
-- ----------------------------
-- Table structure for votes
-- ----------------------------
DROP TABLE IF EXISTS `votes`;
CREATE TABLE `votes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of votes
-- ----------------------------
INSERT INTO `votes` VALUES ('1', 'Very good');
INSERT INTO `votes` VALUES ('2', 'Good');
INSERT INTO `votes` VALUES ('3', 'Regular');
Much appreciate your support, thank you very much.
Your third part isn't clear. But the second part can be solved by:
SELECT
M.name AS title_movie,
M.year AS premiere,
G.name AS gender,
COUNT(MHR.vote_id) AS total_voting,
-- 2)
COUNT(MHR.vote_id = 1 OR NULL) AS count_very_good,
COUNT(MHR.vote_id = 2 OR NULL) AS count_good,
COUNT(MHR.vote_id = 3 OR NULL) AS count_regular
FROM movies M
LEFT JOIN gender G ON M.gender_id = G.id
LEFT JOIN movies_has_rating MHR ON M.id = MHR.movie_id
GROUP BY M.id
ORDER BY M.id DESC
http://sqlfiddle.com/#!9/5ba403/5
I'm sure you know how to calculate the percentages from that result.
Update: So OP asks to determine the vote type with the highest count and calculate its percantage within SQL. You can (but you should not) do it with the folowing query:
SELECT t.*,
CASE
WHEN highest_votes_id = 1
THEN 100 * count_very_good / total_voting
WHEN highest_votes_id = 2
THEN 100 * count_good / total_voting
WHEN highest_votes_id = 3
THEN 100 * count_regular / total_voting
END AS highest_votes_percentage
FROM (
SELECT t.*,
CASE
WHEN count_regular > count_good AND count_regular > count_very_good
THEN 3
WHEN count_good > count_very_good
THEN 2
ELSE 1
END AS highest_votes_id
FROM (
SELECT
M.id,
M.name AS title_movie,
M.year AS premiere,
G.name AS gender,
COUNT(MHR.vote_id) AS total_voting,
COUNT(MHR.vote_id = 1 OR NULL) AS count_very_good,
COUNT(MHR.vote_id = 2 OR NULL) AS count_good,
COUNT(MHR.vote_id = 3 OR NULL) AS count_regular
FROM movies M
LEFT JOIN gender G ON M.gender_id = G.id
LEFT JOIN movies_has_rating MHR ON M.id = MHR.movie_id
GROUP BY M.id
) t
) t
ORDER BY t.id DESC
http://sqlfiddle.com/#!9/5ba403/7
How ever you solve that problem in SQL, you will end up with unreasonable ugly code. You better do it in PHP.
if ($row['count_regular'] > $row['count_good'] &&
$row['count_regular'] > $row['count_very_good']
) {
$highestVoteType = 'Regular';
$highestVoteCount = $row['count_regular'];
} elseif ($row['count_good'] > $row['count_very_good']) {
$highestVoteType = 'Good';
$highestVoteCount = $row['count_good'];
} else {
$highestVoteType = 'Very Good';
$highestVoteCount = $row['count_very_good'];
}
if ($row['total_voting'] != 0) {
$highestVotePercantage = 100 * $highestVoteCount / $row['total_voting'];
} else {
$highestVotePercantage = null;
}
1)
Select movies_has_rating.movie_id,movies.name,count(movies_has_rating.vote_id) FROM movies_has_rating JOIN movies ON movies_has_rating.movied_id=movies.id

SUM() Query Giving Wrong Results

I have three tables in my database - staff, salary, shift.
Shift table is linked to the staff table by the staff_id, and salary by the salary_band_id which is also in staff table.
I'm trying to calculate staffs wage by doing (Shift.Total_Hours * Salary.Hourly_Wage)
Here is my query:
SELECT Staff.First_Name, Staff.Last_Name, Shift.Staff_ID, Shift.Total_Hours, Sa.Hourly_Wage,
SUM(Shift.Total_Hours * Sa.Hourly_Wage) Total
FROM Shift, Salary Sa, Staff
INNER JOIN Salary ON Staff.Salary_Band_ID = Salary.Salary_Band_ID
WHERE Shift.Staff_ID = Staff.Staff_ID
GROUP by Staff_ID
ORDER BY Total;
Tables:
CREATE TABLE Shift (
Staff_ID INT(5) NOT NULL,
Date DATE NOT NULL,
Time_Started TIME NOT NULL,
Time_Ended TIME NOT NULL,
Total_Hours DOUBLE(4,2) NOT NULL,
Confirmed ENUM('y','n') NOT NULL
)
INSERT INTO Shift
(Staff_ID, Date, Time_Started, Time_Ended, Total_Hours, Confirmed)
VALUES
('1', '2012-06-08', '9:00', '16:45', '7.75', 'y'),
('3', '2012-06-18', '13:10', '17:30', '4.33', 'y'),
('6', '2012-10-14', '11:15', '16:45', '5.5', 'y'),
('4', '2012-10-30', '10:00', '17:00', '7', 'n'),
('5', '2013-07-15', '9:10', '17:20', '8.1', 'y'),
('10', '2013-08-10', '9:00', '17:00', '8', 'n'),
('8', '2013-10-05', '10:15', '17:30', '7.25', 'y'),
('7', '2013-11-06', '9:20', '17:00', '7.66', 'y'),
('2', '2014-03-25', '9:00', '16:45', '7.75', 'n'),
('9', '2014-04-11', '9:00', '17:00', '8', 'n'),
('11', '2014-06-05', '9:00', '17:00', '8', 'y');
CREATE TABLE Salary (
Salary_Band_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Position VARCHAR(40) NOT NULL,
Hourly_Wage DOUBLE(4,2) NOT NULL
)
INSERT INTO Salary
(Position, Hourly_Wage)
VALUES
('Worker', '6'),
('Worker Manager', '8'),
('General Manager', '10.22'),
('Manager', '13.45'),
('Owner', '25'),
('Brewer', '7.76'),
('Shop Assistant', '6.12');
CREATE TABLE Staff (
Staff_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Salary_Band_ID INT(5) NOT NULL,
First_Name VARCHAR(25) NOT NULL,
Last_Name VARCHAR(25) NOT NULL,
Part_Full_Time ENUM('f','p') NOT NULL,
DOB DATE NOT NULL,
Start_Date DATE NOT NULL,
End_Date DATE,
Address_ID INT(7) NOT NULL,
Contact_Number VARCHAR(12) NOT NULL,
Availability_ID INT(5) NOT NULL,
Brewery_ID INT(4),
Shop_ID INT(4)
)
INSERT INTO Staff
(Salary_Band_ID, First_Name, Last_Name, Part_Full_Time, DOB, Start_Date, Address_ID, Contact_Number, Availability_ID, Brewery_ID, Shop_ID)
VALUES
('1', 'Jenny', 'Bolick', 'p', '1966-08-15', '2005-06-06', '1', '+447700900969', '1', '1', '1'),
('2', 'Margit', 'Eves', 'f', '1968-01-13', '2005-10-06', '2', '07700900711', '1', '1', '2'),
('3', 'Ramonita', 'Layton', 'f', '1975-11-28', '2005-09-29', '3', '07700900336', '1', '1', '1'),
('4', 'Kattie', 'Speck', 'p', '1977-10-24', '2006-09-07', '6', '07700900615', '1', '1', '2'),
('5', 'Christa', 'Denk', 'p', '1968-03-25', '2008-04-11', '5', '07700900542', '2', '2', '4'),
('6', 'Francene', 'Scholl', 'p', '1991-08-05', '2009-05-06', '12', '07700900763', '2', '1', '4'),
('7', 'Patti', 'Tomaszewski', 'f', '1974-01-22', '2010-03-11', '11', '07700900125', '3', '2', '6'),
('7', 'Pandora', 'Laplant', 'p', '1982-02-14', '2011-10-03', '11', '+447700900118', '2', '3', '5'),
('1', 'Branden', 'Bermejo', 'f', '1985-08-15', '2012-04-18', '10', '07700900687', '4', '3', '6'),
('1', 'Lanell', 'Delao', 'p', '1987-12-24', '2012-04-20', '9', '07700900057', '5', '3', '2'),
('1', 'Floria', 'Vandermark', 'f', '1991-03-13', '2013-11-13', '6', '07700900396', '6', '4', '2');
The results all look OK, except the Totals are way off! Also it seems to only pick one salary_band.. £6.60/hour Can anyone see what I'm doing wrong?
I think this is what you are looking for, use explicit JOIN instead of implicit.
SELECT
st.First_Name,
st.Last_Name,
sh.Staff_ID,
sh.Total_Hours,
sa.Hourly_Wage,
SUM(sh.Total_Hours * sa.Hourly_Wage) Total
from Staff st
inner join Salary sa on sa.Salary_Band_ID = st.Salary_Band_ID
inner join Shift sh on sh.Staff_ID = st.Staff_ID
GROUP by st.Staff_ID
ORDER BY Total
desc
;
DEMO

MYSQL Database query to return highest score

Hello im working on database for school using mysql. I got stuck on the query to return student with the highest score. I tried different combinations of queries and none of them worked. Some returned all students with grade 100 (note only one of my students have grade 100 in the test data) and other returned First student in test data with grade 100. I suspect there is an error in my database but i cannot solve it.
DB:
CREATE TABLE Student
(
StudentID INT auto_increment,
ClassID VARCHAR(10),
FirstName VARCHAR(25),
LastName VARCHAR(25),
DateOfBirth DATE,
Gender VARCHAR(10),
PRIMARY KEY (StudentID, ClassID)
);
create table Subjects
(
SubjectID INT,
SubjectName VARCHAR(25),
PRIMARY KEY (SubjectID)
);
create table Grade
(
StudentID INT,
SubjectID INT,
ClassID VARCHAR(10),
Grade DECIMAL(5,1),
FOREIGN KEY (StudentID) REFERENCES Student(StudentID),
FOREIGN KEY (SubjectID) REFERENCES Subjects(SubjectID),
FOREIGN KEY (ClassID) REFERENCES Student(ClassID)
);
Test data:
INSERT INTO Student (StudentID, ClassID, FirstName, LastName, DateOfBirth, Gender)
VALUES ('', '01', 'John', 'Smith', '15/01/2000', 'Male'),
('', '01', 'Michael', 'Black', '15/03/2000', 'Male'),
('', '01', 'Dennis', 'White', '07/08/1999', 'Male'),
('', '01', 'Emy', 'Blue', '10/04/2000', 'Female'),
('', '01', 'Joe', 'Yellow', '09/05/2000', 'Male'),
('', '01', 'Aaren', 'Jackson', '09/009/1999', 'Male'),
('', '01', 'Marta', 'Harris', '30/01/2000', 'Female'),
('', '01', 'Laura', 'Lewis', '09/01/2000', 'Female'),
('', '01', 'Michael', 'Jackson', '01/01/2000', 'Male'),
('', '02', 'Piotr', 'Kowalski', '15/01/2000', 'Male'),
('', '02', 'Harris', 'Bialy', '15/03/2000', 'Male'),
('', '02', 'Porter', 'Czarny', '07/08/1999', 'Male'),
('', '02', 'Maciek', 'Blue', '10/04/2000', 'Female'),
('', '02', 'Mateusz', 'Yellow', '09/05/2000', 'Male'),
('', '02', 'Aaren', 'Jackson', '09/009/1999', 'Male'),
('', '02', 'Marta', 'Harris', '30/01/2000', 'Female'),
('', '02', 'Laura', 'Lewis', '09/01/2000', 'Female'),
('', '02', 'Chaytan', 'Jackson', '01/01/2000', 'Male');
INSERT INTO Subjects (SubjectID, SubjectName)
VALUES ('01', 'English'),
('02', 'Mathematics'),
('03', 'Science'),
('04', 'Geography'),
('05', 'IT'),
('06', 'History');
INSERT INTO Grade (StudentID, SubjectID, ClassID, Grade)
VALUES ('01', '1', '01', '60.5'),
('01', '2', '01', '70.0'),
('01', '3', '01', '40.0'),
('01', '4', '01', '33.5'),
('01', '5', '01', '90.0'),
('01', '6', '01', '77.5'),
('01', '7', '01', '89.0'),
('01', '8', '01', '74.0'),
('01', '9', '01', '66.5'),
('01', '10', '02', '30.5'),
('01', '11', '02', '50.0'),
('01', '12', '02', '30.0'),
('01', '13', '02', '73.5'),
('01', '14', '02', '70.0'),
('01', '15', '02', '57.5'),
('01', '16', '02', '69.0'),
('01', '17', '02', '34.0'),
('01', '18', '02', '76.5'),
('02', '1', '01', '65.5'),
('02', '2', '01', '73.0'),
('02', '3', '01', '41.0'),
('02', '4', '01', '39.5'),
('02', '5', '01', '96.0'),
('02', '6', '01', '70.5'),
('02', '7', '01', '80.0'),
('02', '8', '01', '74.0'),
('02', '9', '01', '64.5'),
('02', '10', '02', '55.5'),
('02', '11', '02', '43.0'),
('02', '12', '02', '61.0'),
('02', '13', '02', '49.5'),
('02', '14', '02', '76.0'),
('02', '15', '02', '80.5'),
('02', '16', '02', '99.0'),
('02', '17', '02', '100.0'),
('02', '18', '02', '55.5');
Can you see where have i gone wrong? Could you also tell me appropriate query to retrieve student with highest score. Thanks
I think this is what you want, this will get you the student with the highest score on each subject, if you want a particular subject, you can change WHERE SubjectID=Subjects.SubjectID to WHERE SubjectID=particular_subject_id
SELECT Student.FirstName, Subjects.SubjectName, Grade.Grade, Subjects.SubjectID FROM
Student INNER JOIN Grade ON Grade.StudentID=Student.StudentID
INNER JOIN Subjects ON Grade.SubjectID=Subjects.SubjectID WHERE Grade.Grade=
(SELECT MAX(Grade) FROM Grade WHERE SubjectID=Subjects.SubjectID)
For average:
SELECT Subjects.SubjectName, AVG(Grade.Grade), Grade.ClassID, Subjects.SubjectID
FROM Grade INNER JOIN Subjects ON Grade.SubjectID=Subjects.SubjectID
GROUP BY Grade.ClassID, Grade.SubjectID;
Here's a working fiddle to see results of highest score and average.
You should try this one as also correct answer:
SELECT
A.FirstName,
C.SubjectName,
B.Grade,
C.SubjectID
FROM Student AS A
INNER JOIN Grade AS B ON B.StudentID=A.StudentID
INNER JOIN Subjects AS C ON B.SubjectID=C.SubjectID
WHERE B.Grade=(SELECT MAX(Grade) FROM Grade WHERE SubjectID=C.SubjectID)
fiddle
If I'm understanding your correctly something like this should work:
select s.* from Students s
join Grades g on a.StudentID = s.StudentID
where s.StudentID = (select max(Grade) from Grades);