So I spent today working on these questions to improve my sql, could the answers be improved? tables and answers below
CREATE TABLE IF NOT EXISTS `branch` (
`division` int(11) NOT NULL DEFAULT '0',
`divname` varchar(10) DEFAULT NULL,
`city` varchar(10) DEFAULT NULL,
PRIMARY KEY (`division`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `branch`
--
INSERT INTO `branch` (`division`, `divname`, `city`) VALUES
(10, 'Admin', 'London'),
(20, 'Sales', 'Bristol'),
(30, 'Consulting', 'London'),
(40, 'Training', 'Manchester'),
(50, 'Computing', 'Birmingham');
-- --------------------------------------------------------
--
-- Table structure for table `car`
--
CREATE TABLE IF NOT EXISTS `car` (
`snum` int(11) DEFAULT NULL,
`regno` varchar(9) NOT NULL DEFAULT '',
`make` varchar(20) DEFAULT NULL,
`model` varchar(20) DEFAULT NULL,
`mileage` decimal(10,0) DEFAULT NULL,
PRIMARY KEY (`regno`),
KEY `car_fk1` (`snum`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `car`
--
INSERT INTO `car` (`snum`, `regno`, `make`, `model`, `mileage`) VALUES
(3107, 'G343ALJ', 'BMW', '316i', '27216'),
(3200, 'F260PQN', 'Ford', 'Sierra', '30986'),
(3414, 'E329WUF', 'Volvo', '340', '28216'),
(3698, 'G181BSS', 'Ford', 'Sierra', '18311'),
(3724, 'G213CBS', 'Ford', 'Orion', '20016'),
(3788, 'G268JFN', 'Volvo', '440', '16485'),
(3812, 'H989TNP', 'Toyota', 'Lexus', '2193'),
(3813, 'F138RUS', 'BMW', '320', '28726');
-- --------------------------------------------------------
--
-- Table structure for table `staff`
--
CREATE TABLE IF NOT EXISTS `staff` (
`snum` int(11) NOT NULL DEFAULT '0',
`surname` varchar(10) DEFAULT NULL,
`jobtitle` varchar(10) DEFAULT NULL,
`super` int(11) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`joindate` date DEFAULT NULL,
`division` int(11) DEFAULT NULL,
`salary` int(11) DEFAULT NULL,
`bonus` smallint(6) DEFAULT NULL,
PRIMARY KEY (`snum`),
KEY `staff_fk1` (`division`),
KEY `staff_fk2` (`super`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `staff`
--
INSERT INTO `staff` (`snum`, `surname`, `jobtitle`, `super`, `sex`, `joindate`, `division`, `salary`, `bonus`) VALUES
(3926, 'Towlson', 'Chairman', NULL, 'F', '1984-07-11', 10, 45816, NULL),
(3407, 'Macrae', 'Secretary', 3926, 'F', '1982-12-13', 10, 16200, NULL),
(3812, 'Khan', 'Director', 3926, 'M', '1982-12-14', 20, 42000, 950),
(3813, 'Bate', 'Director', 3926, 'F', '1970-04-20', 10, 46752, NULL),
(3200, 'Raines', 'Manager', 3812, 'F', '1980-07-01', 20, 25872, 500),
(3414, 'Welham', 'Manager', 3813, 'M', '1987-06-22', 10, 25872, NULL),
(3107, 'Hamilton', 'Salesman', 3200, 'M', '1982-12-13', 20, 18534, 4500),
(3215, 'Tringham', 'Clerk', 3200, 'M', '1981-03-16', 20, 9384, NULL),
(3016, 'Brock', 'Secretary', 3414, 'F', '1983-06-11', 10, 12288, NULL),
(3365, 'Hughes', 'Accountant', 3414, 'M', '1983-11-17', 10, 23760, NULL),
(3788, 'Kumar', 'Manager', 3813, 'M', '1975-02-10', 30, 30816, 1586),
(3488, 'Styles', 'Clerk', 3365, 'F', '1982-12-01', 10, 8652, NULL),
(3698, 'French', 'Consultant', 3788, 'M', '1980-04-01', 30, 20184, 0),
(3724, 'Adye', 'Consultant', 3788, 'M', '1969-10-28', 30, 29400, 825),
(3989, 'Bray', 'Consultant', 3788, 'M', '1973-09-24', 30, 18000, 825);
Answers :
1. Find the registration number and mileage for each FORD car
SELECT mileage, model, regno FROM car WHERE make = 'Ford'
2. List all the different job titles held by females.
SELECT jobtitle FROM staff WHERE sex = 'F'
3. Show for each vehicle registration and make, the branch name and city as well.
SELECT regno, make, divname, city FROM car c, branch b, staff s
WHERE s.division=b.division AND s.snum=c.snum
4. Find the salaries for London personnel.
SELECT salary, city FROM staff s, branch b
WHERE b.city = 'London' AND b.division=s.division
5. Find personnel details ordered by division, job title and salary (highest first).
SELECT surname, salary,jobtitle, b.division FROM staff s, branch b
WHERE b.division=s.division
ORDER BY b.division, salary DESC
Exercise 3 – moderate queries 6. Find those personnel who started between 1983 and 1987 and have no bonus (Hint: Use the SQL reserved words BETWEEN, AND, IS NULL).
SELECT surname FROM staff WHERE bonus IS NULL AND joindate BETWEEN '83-01-01' and '87-12-31'
7. How many vehicles are there in total? And how many are there of each make? Two separate queries.
SELECT count(make) from car ;
SELECT count(make) from car group by make;
8. Find the average and maximum salaries for consultants.
SELECT MAX(salary), AVG(salary) FROM staff
9. Find staff whose salaries exceed the mileage of the car they drive and by how much! (silly query but ……………!!!!!)
SELECT surname, mileage-salary FROM staff s, car c WHERE mileage>salary AND s.snum=c.snum
10. What is the average, maximum and minimum salary for each division name (use suitable aliases for your output)?
SELECT division, MAX(salary) AS Highest, AVG(salary) AS Average, MIN(salary) AS Lowest FROM staff
GROUP BY division
- Find the staff names and division names for those who drive a FORD with registration numbers starting with G.
SELECT surname, divname from staff s,branch b,car c where make='Ford' and regno like 'G%' and b.division=s.division and s.snum=c.snum;
- Find the total staff cost for the sales division; use NVL(Bonus,0) to convert null bonuses. Exercise
select salary+coalesce(bonus,0) from staff s, branch b where divname='sales' and s.division=b.division
- How many staff does each staff member manage? Your query will probably not show staff who do not manage. Modify the query to include them too.
SELECT s.snum, s.surname, COUNT(s.snum) AS manager FROM staff s, staff s2 Where s.snum=s2.super GROUP BY s.snum,s.surname;
- Show the manager code and number of staff managed for staff who manage at least 2 others.
SELECT super, COUNT(snum) as manaer FROM staff GROUP BY super HAVING COUNT(snum)>=2
- Print staff details with the same job title but different divisions.
SELECT s.surname, s2.surname,s.jobtitle,s.division,s2.division FROM staff s, staff s2 WHERE s.jobtitle=s2.jobtitle AND NOT(s.division=s2.division);
- How many staff are managed by Kumar?
SELECT count(*) as count FROM staff s, staff s2 WHERE s.surname='Kumar' and s.snum=s2.super;
- Show the full details of all staff who are not managers.
SELECT s.* FROM staff s LEFT JOIN staff s2 ON s.snum=s2.super WHERE s2.super is null;
- Show division code and name, average salary and range of salaries (highest minus lowest) for the branches with average salary above 25000.
SELECT p.division,b.divname, AVG(p.salary) AS Average, MAX(p.salary)-MIN(p.salary) difference FROM staff p, branch b where p.division=b.division GROUP BY p.division,b.divname HAVING AVG(salary)>25000;