├── Airline Flight SQL Exercise.sql ├── Employee Department SQL Exercise.sql ├── Population SQL Query Exercise.sql ├── Real SQL Queries 50 Challenges.txt ├── SQL Movie Rating Exercise - Stanford.sql ├── Social Network Exercise Stanford.sql └── Student Faculty SQL Exercise.sql /Airline Flight SQL Exercise.sql: -------------------------------------------------------------------------------- 1 | Flights(flno, from, to, distance,departs, arrives, price) 2 | Aircraft(aid, aname, cruisingrange) 3 | Certified(eid, aid) 4 | Employees(eid, ename, salary) 5 | 6 | --1. Find the names of aircraft such that all pilots certified to operate them earn more than 80,000 7 | 8 | select distinct x.aname from 9 | (select a.aname,MIN(case when e.salary<80000 then 0 else 1 end) as Sal 10 | from Certified c join Employees e 11 | on c.eid=e.eid 12 | join Aircraft a 13 | on a.aid=c.aid 14 | group by a.aname 15 | having MIN(case when e.salary<80000 then 0 else 1 end)=1 ) x 16 | 17 | --2. For each pilot who is certified for more than three aircraft, find the eid and the maximum cruisingrange of the aircraft that he (or she) is certified for. 18 | 19 | select x.eid,x.max_range from 20 | (select e.eid,count(distinct a.aid),max(a.cruisingrange) as max_range 21 | from Certified e join Aircraft a 22 | on c.aid=a.aid 23 | group by e.eid 24 | having count(distinct a.aid)>3 ) x 25 | 26 | --3. Find the names of pilots whose salary is less than the price of the cheapest route from Los Angeles to Honolulu 27 | 28 | select ename from Employees where salary< 29 | (select min(price) from Flights where from='Los Angeles' and to='Honolulu') 30 | 31 | --4. For all aircraft with cruisingrange over 1,000 miles, find the name of the aircraft and the average salary of all pilots certified for this aircraft 32 | 33 | select a.aname,avg(e.salary) as avg_pilot_salary 34 | from Certified c join Aircraft a 35 | on c.aid=a.aid 36 | join Employees e 37 | on e.eid=c.eid 38 | where a.cruisingrange>1000 39 | group by a.aname 40 | 41 | --5. Find the names of pilots certified for some Boeing aircraft 42 | 43 | select distinct e.ename 44 | from Certified c join Aircraft a 45 | on c.aid=a.aid 46 | join Employees e 47 | on e.eid=c.eid 48 | where lower(a.aname) like '%boeing%' 49 | 50 | --6. Find the aids of all aircraft that can be used on routes from Los Angeles to Chicago 51 | 52 | SELECT A.aid 53 | FROM Aircraft A 54 | WHERE A.cruisingrange > 55 | ( SELECT MIN (F.distance) FROM Flights F WHERE F.from = 'Los Angeles' AND F.to = 'Chicago') 56 | 57 | --7. Identify the routes that can be piloted by every pilot who makes more than $100,000 58 | 59 | select x.from,x.to from 60 | (select distinct f.from,f.to,count(distinct c.eid) as pilot_certification 61 | from Flights f join Aircraft a 62 | on f.flno=a.aid 63 | join Certified c 64 | on c.aid=a.aid 65 | join Employees e 66 | on e.eid=c.eid 67 | where c.Salary>1000000 and f.distance>a.cruisingrange 68 | group by f.from,f.to 69 | having count(distinct c.eid)=(select count(distinct eid) from Employees where salary>1000000)x 70 | 71 | --8. Print the enames of pilots who can operate planes with cruisingrange greater than 3,000 miles, but are not certified on any Boeing aircraft 72 | select distinct e.ename 73 | from Aircraft a join Certified c 74 | on a.aid=c.aid 75 | join Employees e 76 | on c.eid=e.eid 77 | where a.cruisingrange>3000 78 | and c.aid not IN 79 | (select distinct aid from Aircarft where aname like 'Boeing%' ) 80 | 81 | --9. A customer wants to travel from Madison to New York with no more than two changes of flight. List the choice of departure times from Madison 82 | -- if the customer wants to arrive in New York by 6 p.m 83 | 84 | SELECT F.departs 85 | FROM Flights F 86 | WHERE F.flno IN ( 87 | ( SELECT F0.flno 88 | FROM Flights F0 89 | WHERE F0.from = 'Madison' AND F0.to = 'New York' 90 | AND F0.arrives < '18:00' ) 91 | UNION 92 | ( SELECT F0.flno 93 | FROM Flights F0, Flights F1 94 | WHERE F0.from = 'Madison' AND F0.to <> 'New York' 95 | AND F0.to = F1.from AND F1.to = 'New York' 96 | AND F1.departs > F0.arrives 97 | AND F1.arrives < '18:00' ) 98 | UNION 99 | ( SELECT F0.flno 100 | FROM Flights F0, Flights F1, Flights F2 101 | WHERE F0.from = 'Madison' 102 | AND F0.to = F1.from 103 | AND F1.to = F2.from 104 | AND F2.to = 'New York' 105 | AND F0.to <> 'New York' 106 | AND F1.to <> 'New York' 107 | AND F1.departs > F0.arrives 108 | AND F2.departs > F1.arrives 109 | AND F2.arrives < '18:00' )) 110 | 111 | --10. Compute the difference between the average salary of a pilot and the average salary of all employees (including pilots) 112 | 113 | SELECT Temp1.avgsal - Temp2.avgsal 114 | FROM (SELECT AVG (E.salary) AS avgsal 115 | FROM Employees E 116 | WHERE E.eid IN (SELECT DISTINCT C.eid 117 | FROM Certified C )) AS Temp1, 118 | (SELECT AVG (E1.salary) AS avgsal 119 | FROM Employees E1 ) AS Temp2 120 | 121 | --11. Print the name and salary of every nonpilot whose salary is more than the average salary for pilots 122 | 123 | select e.name,e.salary 124 | from Employees e left join Certified c 125 | on e.eid=c.eid 126 | where c.eid is null and e.salary > 127 | (SELECT AVG (E.salary) AS avgsal 128 | FROM Employees E 129 | WHERE E.eid IN (SELECT DISTINCT C.eid FROM Certified C )) 130 | 131 | --12. Print the names of employees who are certified only on aircrafts with cruising range longer than 1000 miles 132 | 133 | select x.ename from 134 | (select e.ename,min(case when a.cruisingrange>1000 then 1 else 0 end ) as range 135 | from Certified c join Aircraft a 136 | on c.aid=a.aid 137 | join Employees e 138 | on e.eid=c.eid 139 | group by e.ename 140 | having min(case when a.cruisingrange>1000 then 1 else 0 end )=1) x 141 | 142 | --13. Print the names of employees who are certified only on aircrafts with cruising range longer than 1000 miles, but on at least two such aircrafts 143 | 144 | select distinct x.ename from 145 | (select e.ename,min(case when a.cruisingrange>1000 then 1 else 0 end ) as range,count(*) as no_aircrafts 146 | from Certified c join Aircraft a 147 | on c.aid=a.aid 148 | join Employees e 149 | on e.eid=c.eid 150 | group by e.ename 151 | ) x 152 | where x.range=1 and x.no_aircrafts>=2 153 | 154 | --14. Print the names of employees who are certified only on aircrafts with cruising range longer than 1000 miles and who are certified on some Boeing aircraft. 155 | 156 | select distinct x.ename from 157 | (select e.ename,min(case when a.cruisingrange>1000 then 1 else 0 end ) as range,max(case when a.aname like 'Boeing%' then 1 else 0 end) as flight_name 158 | from Certified c join Aircraft a 159 | on c.aid=a.aid 160 | join Employees e 161 | on e.eid=c.eid 162 | group by e.ename 163 | ) x 164 | where x.range=1 and x.flight_name=1 -------------------------------------------------------------------------------- /Employee Department SQL Exercise.sql: -------------------------------------------------------------------------------- 1 | --Emp(eid, ename, age, salary) 2 | --Works(eid, did, pct_time) 3 | --Dept(did, dname, budget, managerid) 4 | 5 | --1. Print the names and ages of each employee who works in both the Hardware department and the Software department 6 | 7 | SELECT distinct E.ename, E.age 8 | FROM Emp E, Works W1, Works W2, Dept D1, Dept D2 9 | WHERE E.eid = W1.eid AND W1.did = D1.did AND D1.dname = 'Hardware' 10 | AND E.eid = W2.eid AND W2.did = D2.did AND D2.dname = 'Software' 11 | 12 | --2. For each department with more than 20 full-time-equivalent employees (i.e.,where the part-time and full-time employees add up to at least that many fulltime 13 | --employees), print the did together with the number of employees that work in that department 14 | 15 | SELECT W.did, COUNT (W.eid) 16 | FROM Works W 17 | GROUP BY W.did 18 | HAVING 2000 < 19 | ( SELECT SUM (W1.pct time) 20 | FROM Works W1 21 | WHERE W1.did = W.did ) 22 | 23 | --3. Print the name of each employee whose salary exceeds the budget of all of the departments that he or she works in 24 | 25 | select distinct x.ename from 26 | (select e.ename,e.salary as sal,max(d.budget) as budget 27 | from Emp e join Works w 28 | on e.eid=w.eid 29 | join Dept d 30 | on d.did=w.did 31 | group by e.ename,e.salary) x 32 | where x.sal>x.budget 33 | 34 | --4. Find the managerids of managers who manage only departments with budgets greater than $1 million 35 | 36 | select managerid from 37 | (select managerid,min(budget) 38 | from Dept 39 | group by managerid 40 | having min(budget)>1000000) x 41 | 42 | --5. Find the enames of managers who manage the departments with the largest budgets 43 | 44 | select distinct ename from Dept d join Emp e on e.eid = d.managerid 45 | where d.budget=(select max(budget) from Dept) 46 | 47 | --6. If a manager manages more than one department, he or she controls the sum of all the budgets for those departments. Find the managerids of managers 48 | --who control more than $5 million 49 | 50 | select x.managerid from 51 | (select managerid,sum(budget) as total 52 | from Dept 53 | group by managerid 54 | having sum(budget)>5000000 ) x 55 | 56 | 57 | --7. Find the managerids of managers who control the largest amounts 58 | 59 | select x.managerid from 60 | (select managerid,sum(budget) as total,rank() over (order by sum(budget) desc) as ranking 61 | from Dept 62 | group by managerid ) 63 | where x.ranking=1 64 | 65 | --8. Find the enames of managers who manage only departments with budgets larger than $1 million, but at least one department with budget less than $5 million 66 | 67 | SELECT DISTINCT Em.ename 68 | FROM Emp Em, Dept D 69 | WHERE Em.eid In (Select D.managerid 70 | FROM Dept D 71 | WHERE D.budget > 1000000 72 | GROUP BY D.managerid 73 | HAVING MIN(D.budget) < 5000000 74 | ) -------------------------------------------------------------------------------- /Population SQL Query Exercise.sql: -------------------------------------------------------------------------------- 1 | create table states (statecode , population_2010 , population_2000 , population_1950 , population_1900 , landarea , name, admitted_to_union ); 2 | create table counties(name , statecode , population_1950 , population_2010 ); 3 | create table senators(statecode , name , affiliation , took_office, born); 4 | create table committees(id, parent_committee, name, chairman , ranking_member); 5 | 6 | 7 | --1.List all state names and their 2-letter codes. Output columns: name, statecode . Order by the state name. 8 | 9 | select name,statecode 10 | from states 11 | order by name 12 | 13 | --2. Write a query to report the information for all counties whose names start with "Prince" . 14 | --Output columns: name, statecode, populate_1950, populateion_2010 15 | --Order by state code. 16 | 17 | select c.name,c.statecode,c.population_1950,c.population_2010 18 | from counties c 19 | where c.name like 'Prince%' 20 | order by c.statecode 21 | 22 | --3. Write a single query to list only the population in year 2010 for the state represented by Sen. Richard Lugar. 23 | --Output column: populate_2010 24 | 25 | select s.population_2010 26 | from states s join senators se 27 | on s.statecode=se.statecode 28 | where se.name like '%Richard Lugar' 29 | 30 | --4. Write a single query to report only the total number of the counties in 'Maryland'. The query should not hard-code the state code for Maryland. 31 | 32 | select count(c.name) as total_counties 33 | from counties c join states s 34 | on c.statecode=s.statecode 35 | where s.name='Maryland' 36 | 37 | --5. Write a single query to find the name of the state that was admitted last into the union. 38 | 39 | select name 40 | from states where admitted_to_union=(select max(admitted_to_union) from states) 41 | 42 | --6. Write a query to find the names of the counties whose names are at least 20 characters long. Keep in mind that county name is defined to be a fixed-length 43 | --30 character string, so you must elimiated the padded whitespaces to correctly answer the query 44 | --Output columns: name (of the county) 45 | --Order by: name. 46 | 47 | select name 48 | from counties 49 | where LEN(RTRIM(LTRIM(name)))>=20 50 | order by name 51 | 52 | --7. Write a query to find the name of the state with the minimum number of counties. If there are multiple such states, all should be reported. 53 | --Output column: name (of the state) 54 | 55 | select x.name from 56 | (select s.name, rank() over (order by count(*)) as ranking 57 | from states s join counties c 58 | on s.statecode=c.statecode 59 | group by s.name) x 60 | where x.ranking=1 61 | 62 | --8. Create a view called HighPopulationCounties containing the high-population counties (defined to be counties with at least 2.5M population in 2010), 63 | --and their state names. 64 | --View columns: countyname, statename, population_2010 65 | 66 | select c.name as county_name,s.name as state_name,c.population_2010 67 | from states s join counties c 68 | on s.statecode=c.statecode 69 | where c.population_2010>=2500000 70 | order by c.population_2010 desc 71 | 72 | --9. Write a query to find if any senators represent a state that was admitted to the union after they were born. 73 | --Hint: Use "extract" function that operates on the dates. 74 | --Output columns: senator_name, year_born, state_name, year_state_admitted 75 | --Order by senator name. 76 | 77 | select s.name as senator_name,s.born,st.name as state_name,st.admitted_to_union 78 | from senators s join states st 79 | on s.statecode=st.statecode 80 | where YEAR(st.admitted_to_union) > s.born 81 | 82 | --10. Find all democratic (i.e., with affiliation = 'D') senators that are not chairman of any committee or sub-committee. 83 | --Output columns: name 84 | --Order by name. 85 | 86 | select distinct s.name as senator_name 87 | from senators s left outer join committees c 88 | on s.name=c.chairman 89 | where c.chairman is null and s.affiliation='D' 90 | order by s.name 91 | 92 | --11. Create a table (call it PopulationGrowth), that contains three columns: statename, growth_1900_to_1950, growth_1950_to_2000, where the 93 | --growth_1900_to_1950 is defined as: population_1950/population_1900, and the second number is defined similarly. 94 | --List the result of:"select * from PopulationGrowth where growth_1950_to_2000 > 5 order by statename;" 95 | 96 | select name , population_1950/CONVERT(FLOAT,population_1900) as growth_1900_to_1950,population_2000/CONVERT(FLOAT,population_1950) as growth_1950_to_2000 97 | from states 98 | where population_2000/CONVERT(FLOAT,population_1950) >5 99 | order by name 100 | 101 | --12. Write a query to find all the states whose growth rate was higher by a factor of 2 or more in the period 1900 to 1950, than in the period from 1950 to 2000? 102 | --Use PopulationGrowth table created above. For example, if a state grew by a factor of 3 between 1900 and 1950, but only 103 | --by a factor of 1.45 between 1950 and 2000, then it would qualify for the answer. 104 | 105 | select x.name from 106 | (select name , population_1950/CONVERT(FLOAT,population_1900) as growth_1900_to_1950,population_2000/CONVERT(FLOAT,population_1950) as growth_1950_to_2000 107 | from states ) x 108 | where x.growth_1900_to_1950 / x.growth_1950_to_2000>=2 109 | 110 | --13. Write a query to find the day when the 30th state was admitted to the union, and the name of the state. 111 | --Output columns: name, admitted_to_union 112 | 113 | select x.name , x.admitted_to_union from 114 | (select name, admitted_to_union,rank() over (order by admitted_to_union) as ranking 115 | from states ) x 116 | where x.ranking=30 117 | 118 | --14. Write a query to find the name of the state whose representatives are the ranking members of most committees or subcommittees? 119 | --Here the committees and the subcommittees are counted separately. 120 | 121 | select x.name from 122 | (select states.name, count(*) as num, rank() over(order by count(*) desc) as ranking 123 | from states, senators, committees 124 | where states.statecode = senators.statecode and senators.name = committees.ranking_member 125 | group by states.name) x 126 | where x.ranking=1 127 | 128 | --15. Write a query to find the state that was admitted next after 'Minnesota'. If there are multiple such states (admitted on the same day), all should be reported. 129 | --Make sure the date is reported correct (see question 13). 130 | --Output: name, admitted_to_union 131 | 132 | select x.name,x.admitted_to_union from 133 | (select name , admitted_to_union,rank() over (order by admitted_to_union) as ranking 134 | from states where admitted_to_union>(select admitted_to_union from states where name='Minnesota') 135 | ) x 136 | where x.ranking=1 137 | 138 | --16. Write a query to add a new column called ``num_subcommittees'' to the Committees table. Initially the ``num_subcommittees'' column would be listed as empty. 139 | --Write a query to ``update'' the table to set it appropriately. The columns should be set to 0 if the committee has no sub-committees, to -1 if the committee is 140 | --a sub-committee, and to the number of subcommittees otherwise 141 | 142 | select a.id,a.parent_committee, 143 | case 144 | when a.parent_committee is not null then -1 else (select count(*) from committees b where b.parent_committee = a.id) END as num_subcommittees 145 | from Committees a 146 | 147 | --17. Write a query to find the largest gap (in number of days) between admission of two consecutive states. For example, the gap between Delaware and Pennsylvania 148 | --was 5 days, whereas the gap between Utah and the next state to be admitted, Oklahoma, was almost 11 years 149 | --Output: state_one, state_two, gap (in days) 150 | 151 | select y.state_one,y.state_two,y.gap 152 | from 153 | (select x.state_one,x.state_two,x.gap,rank() over (order by gap desc) as new_rank 154 | from 155 | (select s1.name as state_one, s2.name as state_two, DATEDIFF(DAY,s1.admitted_to_union ,s2.admitted_to_union) as gap, 156 | rank() over (partition by s1.name order by DATEDIFF(DAY,s1.admitted_to_union ,s2.admitted_to_union)) as ranking 157 | from states s1, states s2 158 | where s1.admitted_to_union < s2.admitted_to_union ) x 159 | where x.ranking =1) y 160 | where y.new_rank=1 161 | 162 | --18. As you can see, there is a population field associated with the state, as well as the counties. We would like to make sure that they are consistent, i.e., 163 | --the population of a state is equal to the sum total of populations of its counties. Write a query to check if there is any violation for the 2010 population. 164 | --Output: names of states which violate the property, the two population counts 165 | --Order by: state name 166 | 167 | select x.name , x.population_2010,x.county_population 168 | from 169 | (select s.name,s.population_2010,sum(c.population_2010) as county_population 170 | from states s join counties c 171 | on s.statecode=c.statecode 172 | group by s.name,s.population_2010) x 173 | where x.population_2010<> x.county_population 174 | order by x.name 175 | -------------------------------------------------------------------------------- /Real SQL Queries 50 Challenges.txt: -------------------------------------------------------------------------------- 1 | 1. Year over Year comparison 2 | 3 | select a.SalesPersonID,c.LastName,YEAR(DATEADD(MONTH,6,a.OrderDate)) as FY, 4 | DATEPART(QUARTER,DATEADD(MONTH,6,a.OrderDate)) as FQ, 5 | SUM(a.SubTotal) as FQSales, 6 | SUM(b.SubTotal) as SameSalesFQLast, 7 | SUM(a.SubTotal)-SUM(b.SubTotal) as Change, 8 | ((SUM(a.SubTotal)-SUM(b.SubTotal)) /SUM(b.SubTotal)) * 100 as pct_change 9 | from [Sales].[SalesOrderHeader] a left join [Sales].[SalesOrderHeader] b 10 | on a.SalesPersonID=b.SalesPersonID 11 | and DATEPART(QUARTER,DATEADD(MONTH,6,b.OrderDate))=DATEPART(QUARTER,DATEADD(MONTH,6,a.OrderDate)) 12 | and DATEPART(YEAR,DATEADD(MONTH,6,b.OrderDate))=DATEPART(YEAR,DATEADD(MONTH,6,a.OrderDate))-1 13 | inner join Person.[Person] c 14 | on c.BusinessEntityID=a.SalesPersonID 15 | where DATEPART(YEAR,DATEADD(MONTH,6,a.OrderDate))=2008 16 | group by a.SalesPersonID,c.LastName,YEAR(DATEADD(MONTH,6,a.OrderDate)), 17 | DATEPART(QUARTER,DATEADD(MONTH,6,a.OrderDate)) 18 | 19 | 2. Promotional Effect 20 | 21 | select 22 | a.SalesOrderID, 23 | a.OrderDate, 24 | d.Name as Ship_to_State, 25 | a.SubTotal as Historical_Order_Total, 26 | a.Freight as Historical_Freight, 27 | CASE WHEN a.SubTotal>=1700 and a.SubTotal<2000 THEN 'Increase order to 2000 and pay 22 cents as Freight' WHEN a.SubTotal>=2000 THEN 'No Order Change but pay 22 cents as Freight' ELSE 'No order change and pay historical freight' END as Promo_Effect, 28 | CASE WHEN a.SubTotal>=1700 and a.SubTotal<2000 THEN 2000 - a.SubTotal ELSE 0 END as Potential_Order_Gain, 29 | CASE WHEN a.SubTotal>=1700 THEN 0.22 else a.Freight END - a.Freight as PotentialFreightoss, 30 | (CASE WHEN a.SubTotal>=1700 and a.SubTotal<2000 then 2000 -a.SubTotal ELSE 0 END + CASE WHEN a.SubTotal>=1700 THEN 0.22 ELSE a.Freight END )- a.Freight as PromoNetGain_Loss 31 | from [Sales].[SalesOrderHeader] a join Person.BusinessEntityAddress b 32 | on a.ShipToAddressID=b.AddressID 33 | join Person.[Address] c ON b.AddressID = c.AddressID 34 | join Person.StateProvince d 35 | on c.StateProvinceID=d.StateProvinceID 36 | where d.Name = 'California' and DATEPART (YEAR, DATEADD (MONTH, 6,a.OrderDate)) = 2008 37 | 38 | 39 | 4. Upsell Tuesdays 40 | 41 | select 42 | DAtename(WEEKDAY,a.OrderDate) as Day_of_Week, 43 | count(*) as Orders, 44 | sum(a.SubTotal) as Revenue, 45 | sum(a.SubTotal)/count(*) as Revenue_per_order 46 | from 47 | [Sales].[SalesOrderHeader] a 48 | where a.OnlineOrderFlag=0 and YEAR(a.OrderDate)=2008 49 | group by DAtename(WEEKDAY,a.OrderDate) 50 | ORDER BY sum(a.SubTotal)/count(a.SalesOrderID) desc 51 | 52 | 9. Part 2 53 | 54 | select a.Bikes, a.Accessories,a.Clothing,a.Components,count(distinct a.SalesOrderID) 55 | from 56 | (select b.SalesOrderID, 57 | MAX(case when e.Name='Bikes' THEN 1 ELSE 0 END) as Bikes, 58 | MAX(case when e.Name='Components' THEN 1 ELSE 0 END) as Components, 59 | MAX(case when e.Name='Clothing' THEN 1 ELSE 0 END) as Clothing, 60 | MAX(case when e.Name='Accessories' THEN 1 ELSE 0 END) as Accessories 61 | from [Sales].[SalesOrderDetail] a join [Sales].[SalesOrderHeader] b 62 | on a.SalesOrderID=b.SalesOrderID 63 | join [Production].[Product] c 64 | on a.ProductId=c.ProductID 65 | join [Production].[ProductSubcategory] d 66 | on c.ProductSubcategoryID=d.ProductSubcategoryID 67 | join [Production].[ProductCategory] e 68 | on e.ProductCategoryID=d.ProductCategoryID 69 | group by b.SalesOrderID) a 70 | group by a.Bikes, a.Accessories,a.Clothing,a.Components 71 | order by a.Bikes, a.Accessories,a.Clothing,a.Components 72 | 73 | 9. Part 3 74 | select a.M, a.S,a.T,a.R,count(distinct a.CustomerID) 75 | from 76 | (select b.CustomerID, 77 | MAX(case when c.ProductLine='M' THEN 1 ELSE 0 END) as M, 78 | MAX(case when c.ProductLine='S' THEN 1 ELSE 0 END) as S, 79 | MAX(case when c.ProductLine='T' THEN 1 ELSE 0 END) as T, 80 | MAX(case when c.ProductLine='R' THEN 1 ELSE 0 END) as R 81 | from [Sales].[SalesOrderDetail] a join [Sales].[SalesOrderHeader] b 82 | on a.SalesOrderID=b.SalesOrderID 83 | join [Production].[Product] c 84 | on a.ProductId=c.ProductID 85 | group by b.CustomerID) a 86 | group by a.M, a.S,a.T,a.R 87 | order by a.M, a.S,a.T,a.R 88 | 89 | 12. 90 | select b.name,count(distinct a.ProductID) ProductCount,sum(a.Quantity) as ProductQty 91 | from [Production].[ProductInventory] a join [Production].[Location] b 92 | on a.LocationID=b.LocationID 93 | group by (b.name) 94 | UNION 95 | select 'Total' , count(distinct a.ProductID) ProductCount,sum(a.Quantity) as ProductQty 96 | from [Production].[ProductInventory] a 97 | 98 | 13. 99 | select SUBSTRING(a.NationalIDNumber,LEN(a.NationalIDNumber)-4,4) as ID_NUM , 100 | b.FirstName, 101 | b.LastName, 102 | a.JobTitle, 103 | MAX(a.VacationHours) AS VACHOURS 104 | from 105 | [HumanResources].[Employee] a join [Person].[Person] b 106 | on a.BusinessEntityID=b.BusinessEntityID 107 | group by SUBSTRING(a.NationalIDNumber,LEN(a.NationalIDNumber)-4,4), 108 | b.FirstName, 109 | b.LastName, 110 | a.JobTitle 111 | having MAX(a.VacationHours)=(select max(b.VacationHours) from [HumanResources].[Employee] b) 112 | 113 | 14. 114 | select b.ProductID,c.Name,a.OrderDate,sum(b.OrderQty) as QTY 115 | from [Purchasing].[PurchaseOrderHeader] a join [Purchasing].[PurchaseOrderDetail] b 116 | on a.PurchaseOrderID=b.PurchaseOrderID 117 | join [Production].[Product] c 118 | on b.ProductID=c.ProductID 119 | where YEAR(a.OrderDate)=2007 120 | group by b.ProductID,c.Name,a.OrderDate 121 | order by sum(b.OrderQty) DESC 122 | 123 | 15. 124 | select a.ProductModelID,a.Name,c.Description,b.CultureID 125 | from 126 | [Production].[ProductModel] a join [Production].[ProductModelProductDescriptionCulture] b 127 | on a.ProductModelID=b.ProductModelID join [Production].[ProductDescription] c 128 | on b.ProductDescriptionID=c.ProductDescriptionID 129 | where b.CultureID!='en' 130 | 131 | 16. 132 | select a.TerritoryID, 133 | count(*) as Total_Orders, 134 | ROUND(CONVERT(FLOAT,(SUM(CASE WHEN a.OnlineOrderFlag = 1 THEN 1 ELSE 0 END)))/count(*)* 100,0) as Online_Order, 135 | ROUND(CONVERT(FLOAT,(SUM(CASE WHEN a.OnlineOrderFlag = 0 THEN 1 ELSE 0 END)))/count(*)* 100,0) as Offline_Order 136 | from [Sales].[SalesOrderHeader] a 137 | group by a.TerritoryID 138 | order by a.TerritoryID 139 | 140 | 17. 141 | select a.CustomerID,c.StoreID,b.BusinessEntityID,b.Name,max(a.OrderDate),DATEDIFF(MONTH,max(a.OrderDate),'2008-10-07') 142 | from [Sales].[SalesOrderHeader] a join [Sales].[Customer] c 143 | on a.CustomerID=c.CustomerID join [Sales].[Store] b 144 | on c.StoreID=b.BusinessEntityID 145 | group by a.CustomerID,c.StoreID,b.BusinessEntityID,b.Name 146 | having DATEDIFF(MONTH,max(a.OrderDate),'2008-10-07')>=12 147 | order by DATEDIFF(MONTH,max(a.OrderDate),'2008-10-07') DESC 148 | 149 | 18. 150 | select a.ProductID,a.Name as ProducTName,b.Name as SubCategory, 151 | min(d.StandardCost) as MIN_COST,max(d.StandardCost)as MAX_COST,max(d.StandardCost)-min(d.StandardCost) as variability, 152 | ROW_NUMBER() over (order by max(d.StandardCost)-min(d.StandardCost) DESC) 153 | from 154 | [Production].[Product] a join Production.ProductSubcategory b on 155 | a.ProductSubcategoryID=b.ProductSubcategoryID join [Production].[ProductCostHistory] d 156 | on a.ProductID=d.ProductID 157 | group by a.ProductID,a.Name,b.Name 158 | order by max(d.StandardCost)-min(d.StandardCost) DESC 159 | 160 | 19. 161 | select a.ProductID,a.ProductName,a.Scrapping_Reason,a.WorkOrder_count from 162 | (select a.ProductID,a.Name as ProductName,c.Name as Scrapping_Reason,count(b.WorkOrderID) as WorkOrder_count, 163 | ROW_NUMBER() over (partition by a.ProductID order by count(b.WorkOrderID) DESC) as RANKING 164 | from 165 | [Production].[Product] a join [Production].[WorkOrder] b 166 | on a.ProductID=b.ProductID 167 | join [Production].[ScrapReason] c 168 | on c.ScrapReasonID=b.ScrapReasonID 169 | where b.ScrapReasonID IS NOT NULL 170 | group by a.ProductID,a.Name,c.Name) a 171 | where a.RANKING=1 172 | 173 | 20. 174 | select d.Name as StoreName,a.AddressLine1,a.AddressLine2,a.City,c.Name,a.PostalCode 175 | from [Person].[Address] a join [Person].[BusinessEntityAddress] b 176 | on a.AddressID=b.AddressID 177 | join [Person].[StateProvince] c 178 | on a.StateProvinceID=c.StateProvinceID 179 | join [Sales].[Store] d 180 | on d.BusinessEntityID=b.BusinessEntityID 181 | where b.AddressTypeID=3 and a.City='Toronto' 182 | 183 | 21. 184 | select d.FirstName,d.LastName,c.JobTitle,c.BirthDate,c.MaritalStatus,a.StartDate as Hire_Date 185 | from 186 | [HumanResources].[EmployeeDepartmentHistory] a join [HumanResources].[Department] b 187 | on a.DepartmentID=b.DepartmentID 188 | join [HumanResources].[Employee] c 189 | on c.BusinessEntityID=a.BusinessEntityID 190 | join [Person].[Person] d 191 | on d.BusinessEntityID=a.BusinessEntityID 192 | where (YEAR(a.StartDate)<2002 or YEAR(a.StartDate)>2004) and b.Name='Marketing' and a.EndDate IS NULL 193 | 194 | 22. 195 | select a.ProductReviewID,a.ProductID,b.Name,a.ReviewerName,a.Rating,a.EmailAddress,c.BusinessEntityID 196 | from [Production].[ProductReview] a join [Production].[Product] b 197 | on a.ProductID=b.ProductID 198 | left outer join [Person].[EmailAddress] c 199 | on a.EmailAddress=c.EmailAddress 200 | 201 | 23. 202 | select a.SalesOrderID,a.OrderDate,c.Name,f.FirstName,f.LastName,g.PhoneNumber 203 | from [Sales].[SalesOrderHeader] a join [Sales].[SalesOrderDetail] b 204 | on a.SalesOrderID=b.SalesOrderID 205 | join [Production].[Product] c 206 | on b.ProductID=c.ProductID 207 | join [Sales].[Customer] e 208 | on e.CustomerID=a.CustomerID 209 | join [Person].[Person] f 210 | on e.PersonID=f.BusinessEntityID 211 | join [Person].[PersonPhone] g 212 | on g.BusinessEntityID=f.BusinessEntityID 213 | where a.OrderDate>'2008-07-07' and a.OnlineOrderFlag=1 and LOWER(c.Name) LIKE '%shorts%' 214 | order by a.SalesOrderID 215 | 216 | 24. 217 | select 218 | case 219 | WHEN a.EmailPromotion=0 THEN 'Contact does not wish to receive e-mail Promotions' 220 | WHEN a.EmailPromotion=1 THEN 'Contact dose not wish to receive e-mail promotions from AdventureWorks' 221 | WHEN a.EmailPromotion=2 THEN 'Contact does wish to receive e-mail promotions from AdventureWorks and selected partners' 222 | END as Email_preference 223 | ,count(*) as COUNT_PEOPLE 224 | from [Person].[Person] a 225 | where a.PersonType='IN' 226 | group by 227 | case 228 | WHEN a.EmailPromotion=0 THEN 'Contact does not wish to receive e-mail Promotions' 229 | WHEN a.EmailPromotion=1 THEN 'Contact dose not wish to receive e-mail promotions from AdventureWorks' 230 | WHEN a.EmailPromotion=2 THEN 'Contact does wish to receive e-mail promotions from AdventureWorks and selected partners' 231 | END 232 | 233 | 25. 234 | select a.FiscalYear,a.TerritoryName,a.Revenue,a.Ranking from 235 | (select YEAR(DATEADD(MONTH, 6, a.OrderDate)) as FiscalYear,b.Name as TerritoryName,sum(a.Subtotal) as Revenue, 236 | row_number() over (partition by YEAR(DATEADD(MONTH, 6, a.OrderDate)) order by sum(a.Subtotal) DESC) as RANKING 237 | from [Sales].[SalesOrderHeader] a join [Sales].[SalesTerritory] b 238 | on a.TerritoryID=b.TerritoryID 239 | where YEAR(DATEADD(MONTH, 6, a.OrderDate)) in (2006,2007) 240 | group by YEAR(DATEADD(MONTH, 6, a.OrderDate)) ,b.Name 241 | ) a 242 | where a.RANKING<3 243 | 244 | 26. 245 | select a.BusinessEntityID,max(a.CommissionPct),max(a.Bonus), 246 | row_number() over ( order by max(a.CommissionPct) DESC,max(a.Bonus) DESC) 247 | from [Sales].[SalesPerson] a 248 | group by a.BusinessEntityID 249 | order by max(a.CommissionPct) DESC 250 | 251 | 27. 252 | /* Part 1: Report No of Work Orders by ProductID. Order in DESC order of Work Orders */ 253 | 254 | select a.ProductID,count(a.WorkOrderID) as WorkOrderCount 255 | from [Production].[WorkOrder] a 256 | group by a.ProductID 257 | order by count(a.WorkOrderID) DESC 258 | /* Part 2: Report No of Work Orders by Product Name.Order in DESC order of Work Orders */ 259 | 260 | select b.Name,count(a.WorkOrderID) as WorkOrderCount 261 | from [Production].[WorkOrder] a join [Production].[Product] b 262 | on a.ProductID=b.ProductID 263 | group by b.Name 264 | order by count(a.WorkOrderID) DESC 265 | 266 | 28. 267 | /*Part 1:Using revenue informatiom from May 1st-23rd 2008 estimate revenue for whole month of May 268 | Output: No of days in month so far,Total Revenue in month so far,Revenue per day for month so far,Monthly Revenue trended for all of May*/ 269 | select DATEDIFF(DAY,'2008-05-01','2008-05-23')+ 1 as NofDaysinMonthSoFar, 270 | sum(a.SubTotal) as RevenueinMonthSofar, 271 | (sum(a.SubTotal))/(DATEDIFF(DAY,'2008-05-01','2008-05-23')+ 1) as RevenuePerDay, 272 | DATEDIFF(DAY,'2008-05-01','2008-05-31')+ 1 as DaysinMonth, 273 | (sum(a.SubTotal))/(DATEDIFF(DAY,'2008-05-01','2008-05-23')+ 1) * 31 as MonthlyRevenueTrended 274 | from [Sales].[SalesOrderHeader] a 275 | where a.OrderDate>='2008-05-01'and a.OrderDate<='2008-05-23' 276 | 277 | 278 | /*Part 2:Actual Reveneue Per Day,Actual Revenue*/ 279 | select sum(a.SubTotal)/31 as RevenuePerDay,sum(a.SubTotal) as TotalRevenue 280 | from [Sales].[SalesOrderHeader] a 281 | where a.OrderDate>='2008-05-01'and a.OrderDate<='2008-05-31' 282 | 283 | 29. 284 | 285 | /* Separate usernames from Domains from Employee Table */ 286 | 287 | 288 | select a.BusinessEntityID,a.LoginID, 289 | SUBSTRING(a.LoginID,1,CHARINDEX('\',a.LoginID,1)-1) as Domain, 290 | SUBSTRING(a.LoginID,CHARINDEX('\',a.LoginID,1)+1,LEN(a.LoginID)) as Username 291 | from [HumanResources].[Employee] a 292 | order by a.BusinessEntityID 293 | 294 | 30. 295 | 296 | /* Create a Report with Department Name (Production),Shift Name,Number of Employees */ 297 | 298 | select c.Name as DepartmentName, b.Name as ShiftName,count(a.BusinessEntityID) as NumofEmployees 299 | from [HumanResources].[EmployeeDepartmentHistory] a join [HumanResources].[Shift] b on 300 | a.ShiftID=b.ShiftID 301 | join [HumanResources].[Department] c 302 | on c.DepartmentID=a.DepartmentID 303 | where c.Name='Production' and a.EndDate IS NULL 304 | group by c.Name,b.Name 305 | 306 | 31. 307 | Part 1 308 | /* Determine if variety of labels is sufficient to cover all alpha sized products */ 309 | SELECT DISTINCT Size 310 | FROM Production.Product 311 | WHERE ISNUMERIC (Size) = 0 312 | AND Size IS NOT NULL 313 | 314 | Part 2 315 | select b.Size,sum(a.Quantity) as CurrentQty,case when sum(a.Quantity)-1000 >0 THEN sum(a.Quantity)-1000 ELSE 0 END as AdditionalLabels 316 | from [Production].[ProductInventory] a join Production.Product b 317 | on a.ProductID=b.ProductID 318 | where ISNUMERIC (b.Size) = 0 319 | AND b.Size IS NOT NULL 320 | group by b.Size 321 | 322 | 32. 323 | Part 1: 324 | 325 | /* Total no of employees in the company;% of employees who are Male and Female;Avg no of months of employment. Today is Jan 1st 2008 */ 326 | select 327 | count(a.BusinessEntityID) as EMP_COUNT, 328 | ROUND((sum(case when GENDER='M' THEN 1 ELSE 0 END)/CONVERT(FLOAT,count(a.BusinessEntityID))) * 100,2) as Pct_Male, 329 | ROUND((sum(case when GENDER='F' THEN 1 ELSE 0 END)/CONVERT(FLOAT,count(a.BusinessEntityID))) * 100,2) as Pct_Male, 330 | AVG(DATEDIFF(MONTH,a.HireDate,'2008-01-01')) as AVG_EMPLOYMENT 331 | from [HumanResources].[Employee] a 332 | 333 | Part 2: 334 | 335 | SELECT 336 | X1.Quartile 337 | ,Employees = COUNT (*) 338 | ,[%Male] = ROUND (SUM (CASE WHEN X1.Gender = 'M' THEN 1 ELSE 0 END) / CONVERT (FLOAT, COUNT (*)) * 100, 2) 339 | ,[%Female] = ROUND (SUM (CASE WHEN X1.Gender = 'F' THEN 1 ELSE 0 END) / CONVERT (FLOAT, COUNT (*)) * 100, 2) 340 | ,AvgMonthsEmp = AVG (X1.MonthsEmployed) 341 | FROM (SELECT 342 | BusinessEntityID 343 | ,Quartile = NTILE (4) OVER (ORDER BY DATEDIFF (MONTH, HireDate, '2008-01-01')) 344 | ,HireDate 345 | ,MonthsEmployed = DATEDIFF (MONTH, HireDate, '2008-01-01') 346 | ,Gender 347 | FROM HumanResources.Employee) X1 348 | GROUP BY X1.Quartile 349 | 350 | 33. 351 | select 352 | a.JobTitle, 353 | case 354 | when DATEDIFF(YY,a.BirthDate,'2008-01-01')<18 THEN '<18' 355 | when DATEDIFF(YY,a.BirthDate,'2008-01-01')<35 THEN '18 - 35' 356 | when DATEDIFF(YY,a.BirthDate,'2008-01-01') <50 THEN '36 - 50' 357 | when DATEDIFF(YY,a.BirthDate,'2008-01-01') <60 THEN '51 - 60' 358 | ELSE '61+' 359 | END as AGE_GROUP, 360 | b.Rate, 361 | count(a.BusinessEntityID) as No_of_Emps 362 | from [HumanResources].[Employee] a join [HumanResources].[EmployeePayHistory] b 363 | on a.BusinessEntityID=b.BusinessEntityID 364 | INNER JOIN (SELECT BusinessEntityID, RatechangeDate = MAX (RateChangeDate) 365 | FROM HumanResources.EmployeePayHistory 366 | GROUP BY BusinessEntityID) N3 367 | ON N3.BusinessEntityID = b.BusinessEntityID AND N3.RatechangeDate = b.RateChangeDate 368 | 369 | group by a.JobTitle,case 370 | when DATEDIFF(YY,a.BirthDate,'2008-01-01')<18 THEN '<18' 371 | when DATEDIFF(YY,a.BirthDate,'2008-01-01')<35 THEN '18 - 35' 372 | when DATEDIFF(YY,a.BirthDate,'2008-01-01') <50 THEN '36 - 50' 373 | when DATEDIFF(YY,a.BirthDate,'2008-01-01') <60 THEN '51 - 60' 374 | ELSE '61+' 375 | END,b.Rate 376 | 377 | 34. 378 | select c.Name,sum(a.Subtotal + a.Freight + a.TaxAmt) as revenue 379 | from [Sales].[SalesOrderHeader] a join [Person].[Address] b 380 | on a.ShipToAddressID=b.AddressID 381 | join [Person].[StateProvince] c 382 | on c.StateProvinceID=b.StateProvinceID 383 | where YEAR(a.OrderDate)=2006 384 | group by c.Name 385 | order by sum(a.Subtotal + a.Freight + a.TaxAmt) DESC 386 | 387 | 35. 388 | SELECT TOP 2 389 | N2.FirstName 390 | ,N2.LastName 391 | ,N1.JobTitle 392 | FROM HumanResources.Employee N1 393 | INNER JOIN Person.Person N2 ON N1.BusinessEntityID = N2.BusinessEntityID 394 | 395 | WHERE N1.OrganizationLevel = (SELECT MAX (OrganizationLevel) 396 | FROM HumanResources.Employee) 397 | ORDER BY NEWID () 398 | 399 | 36. 400 | 401 | part 1 402 | select a.SalesOrderID,b.OrderDate,sum(a.OrderQty * a.UnitPrice * a.UnitPriceDiscount) as TotalDiscount 403 | from [Sales].[SalesOrderDetail] a join [Sales].[SalesOrderHeader] b 404 | on a.SalesOrderID=b.SalesOrderID 405 | join [Sales].[SpecialOffer] c 406 | on c.SpecialOfferID=a.SpecialOfferID 407 | where a.UnitPriceDiscount>0 and c.Type='Volume Discount' 408 | group by a.SalesOrderID,b.OrderDate 409 | 410 | Part 2 411 | select YEAR(b.OrderDate),sum(a.OrderQty * a.UnitPrice * a.UnitPriceDiscount) as TotalDiscount 412 | from [Sales].[SalesOrderDetail] a join [Sales].[SalesOrderHeader] b 413 | on a.SalesOrderID=b.SalesOrderID 414 | join [Sales].[SpecialOffer] c 415 | on c.SpecialOfferID=a.SpecialOfferID 416 | where a.UnitPriceDiscount>0 and c.Type='Volume Discount' 417 | group by YEAR(b.OrderDate) 418 | order by YEAR(b.orderdate) 419 | 420 | 37. 421 | 422 | select u.ProductID,MAX(u.MostExpensivePrice) as MostExpensivePrice ,MAX(u.SecondMostExpensivePrice) as SecondMostExpensivePrice, 423 | ROUND((MAX(u.MostExpensivePrice) - MAX(u.SecondMostExpensivePrice))/MAX(u.SecondMostExpensivePrice),2) 424 | from 425 | (select 426 | v.ProductID, 427 | CASE WHEN v.ROWNUM=1 THEN v.LastReceiptCost ELSE NULL END as MostExpensivePrice, 428 | CASE WHEN v.ROWNUM=2 THEN v.LastReceiptCost ELSE NULL END as SecondMostExpensivePrice 429 | from ( 430 | select 431 | a.ProductID, 432 | a.LastReceiptCost, 433 | ROW_NUMBER() over (partition by a.ProductID order by a.LastReceiptCost DESC) as ROWNUM 434 | from [Purchasing].[ProductVendor] a) v 435 | where v.ROWNUM<3) u 436 | group by u.ProductID 437 | having MAX(u.SecondMostExpensivePrice) IS NOT NULL 438 | 439 | 38. 440 | select b.ProductModelID,d.Name as ProductName ,ROUND((b.ListPrice-b.StandardCost)/b.StandardCost,2) 441 | from [Production].[Product] b join [Production].[ProductSubcategory] a 442 | on a.ProductSubcategoryID=b.ProductSubcategoryID 443 | join [Production].[ProductCategory] c 444 | on c.ProductCategoryID=a.ProductCategoryID 445 | join [Production].[ProductModel] d 446 | on d.ProductModelID=b.ProductModelID 447 | where b.SellEndDate IS NULL and c.Name='Bikes' 448 | group by b.ProductModelID,d.Name ,ROUND((b.ListPrice-b.StandardCost)/b.StandardCost,2) 449 | order by ROUND((b.ListPrice-b.StandardCost)/b.StandardCost,2) DESC 450 | 451 | 39. 452 | Part 1 453 | select a.BusinessEntityID,a.QuotaDate,a.SalesQuota,sum(b.SubTotal) as ActualSales , ROUND(sum(b.SubTotal)/(a.SalesQuota),2) 454 | 455 | from [Sales].[SalesPersonQuotaHistory] a 456 | join [Sales].[SalesOrderHeader] b 457 | on a.BusinessEntityID=b.SalesPersonID 458 | and (b.OrderDate>=a.QuotaDate and b.OrderDate$100,000' END as Range, 489 | TotalDue 490 | from [Sales].[SalesOrderHeader] 491 | where year(OrderDate)=2005) a 492 | group by case when a.Range='$0-$100' THEN 1 493 | when a.Range='$100-$500' THEN 2 494 | when a.Range='$500-$1000' THEN 3 495 | when a.Range='$1000-$2500' THEN 4 496 | when a.Range='$2500-$5000' THEN 5 497 | when a.Range='$5000-$10000' THEN 6 498 | when a.Range='$10000-$50000' THEN 7 499 | when a.Range='$50000-$100000' THEN 8 500 | ELSE 9 END , 501 | a.Range 502 | order by 503 | case when a.Range='$0-$100' THEN 1 504 | when a.Range='$100-$500' THEN 2 505 | when a.Range='$500-$1000' THEN 3 506 | when a.Range='$1000-$2500' THEN 4 507 | when a.Range='$2500-$5000' THEN 5 508 | when a.Range='$5000-$10000' THEN 6 509 | when a.Range='$10000-$50000' THEN 7 510 | when a.Range='$50000-$100000' THEN 8 511 | ELSE 9 END 512 | 513 | 41. 514 | select a.PersonType, 515 | sum(case when b.EmailAddress like '%adventure-works.com' THEN 1 ELSE 0 END) as AW_EMAIL, 516 | sum(case when b.EmailAddress not like '%adventure-works.com' THEN 1 ELSE 0 END) as NON_AW_EMAIL, 517 | count(*) 518 | from [Person].[Person] a join [Person].[EmailAddress] b 519 | on a.BusinessEntityID=b.BusinessEntityID 520 | where b.EmailAddress IS NOT NULL 521 | group by a.PersonType 522 | order by sum(case when b.EmailAddress like '%adventure-works.com' THEN 1 ELSE 0 END) DESC 523 | 524 | 42. 525 | /* 5 most successful people to mentor 5 least successful people */ 526 | 527 | select a.SalesPersonID,a.Revenue,b.SalesPersonID,b.Revenue 528 | from 529 | (select a.SalesPersonID,sum(a.SubTotal) as Revenue, 530 | row_number() over (order by sum(a.Subtotal) desc) as TOP_RN 531 | from [Sales].[SalesOrderHeader] a 532 | where YEAR(a.orderdate)=2008 and a.SalesPersonID is NOT NULL 533 | group by a.SalesPersonID) a 534 | join 535 | (select a.SalesPersonID,sum(a.SubTotal) as Revenue, 536 | row_number() over (order by sum(a.Subtotal)) as BOTTOM_RN 537 | from [Sales].[SalesOrderHeader] a 538 | where YEAR(a.orderdate)=2008 and a.SalesPersonID is NOT NULL 539 | group by a.SalesPersonID) b 540 | on a.TOP_RN=b.BOTTOM_RN 541 | where a.TOP_RN<=5 and b.BOTTOM_RN<=5 542 | 543 | 43. 544 | CREATE TABLE HumanResources.Calendar 545 | (DateID INT 546 | ,[Date] DATETIME 547 | ,[Year] INT 548 | ,TextMonth VARCHAR (50) 549 | ,DateMonth DATETIME 550 | ,[DayOfWeek] VARCHAR (50) 551 | ,IsBusinessDay TINYINT) 552 | 553 | DECLARE @StartDate DATETIME = '1990-01-01' 554 | DECLARE @EndDate DATETIME = '2015-01-01' 555 | 556 | DECLARE @TotalDays INT = DATEDIFF (DAY, @StartDate, @EndDate) + 1 ; 557 | 558 | DECLARE @Index INT = 1 559 | 560 | WHILE @Index <= @TotalDays 561 | BEGIN 562 | INSERT INTO HumanResources.Calendar (DateID) 563 | SELECT @Index 564 | SET @Index = @Index + 1 565 | END 566 | 567 | UPDATE N1 568 | SET [Date] = DATEADD (DAY, DateID - 1, @StartDate) 569 | FROM HumanResources.Calendar N1 570 | 571 | UPDATE N1 572 | SET 573 | [Year] = YEAR ([Date]) 574 | ,TextMonth = DATENAME (MONTH, [Date]) + ' ' + DATENAME (YEAR, [Date]) 575 | ,DateMonth = DATEADD (MONTH, DATEDIFF (MONTH, 0, [Date]), 0) 576 | ,[DayOfWeek] = DATENAME (DW, [Date]) 577 | ,IsBusinessDay = CASE WHEN DATENAME (DW, [Date]) IN ('Saturday', 'Sunday') 578 | THEN 0 ELSE 1 END 579 | FROM HumanResources.Calendar N1 580 | 581 | SELECT 582 | [Year] 583 | ,BusinessDays = SUM (IsBusinessDay) 584 | FROM HumanResources.Calendar 585 | GROUP BY [Year] 586 | ORDER BY [Year] 587 | 588 | 44. 589 | SELECT * 590 | ,BusinessEntityOrder = ROW_NUMBER () OVER (PARTITION BY BusinessEntityID 591 | ORDER BY RateChangeDate) 592 | 593 | ,RateEndDate = CONVERT (DATETIME, NULL) 594 | ,BusinessDays = CONVERT (INT, NULL) 595 | INTO #EmployeePayHistory 596 | FROM HumanResources.EmployeePayHistory 597 | 598 | UPDATE N1 599 | SET RateEndDate = (SELECT TOP 1 RateChangeDate 600 | FROM #EmployeePayHistory X1 601 | WHERE N1.BusinessEntityID = X1.BusinessEntityID 602 | AND X1.BusinessEntityOrder = N1.BusinessEntityOrder + 1 603 | ORDER BY X1.RateChangeDate) 604 | FROM #EmployeePayHistory N1 605 | 606 | 607 | UPDATE N1 608 | SET BusinessDays = (SELECT COUNT (*) 609 | FROM HumanResources.Calendar X1 610 | WHERE X1.[Date] BETWEEN N1.RateChangeDate 611 | AND ISNULL (N1.RateEndDate, '2009-01-01') 612 | AND X1.IsBusinessDay = 1) 613 | FROM #EmployeePayHistory N1 614 | 615 | --DROP TABLE #EmployeePayCalendar 616 | 617 | SELECT * 618 | ,DailyPay = Rate * 8 619 | INTO #EmployeePayCalendar 620 | FROM #EmployeePayHistory N1 621 | INNER JOIN HumanResources.Calendar N2 ON 1 = 1 622 | AND N2.[Date] >= N1.RateChangeDate 623 | AND N2.[Date] < ISNULL (N1.RateEndDate, '2009-01-01') 624 | AND N2.IsBusinessDay = 1 625 | 626 | SELECT 627 | BusinessEntityID 628 | ,WorkingYear = [Year] 629 | ,TotalPay = SUM (DailyPay) 630 | FROM #EmployeePayCalendar 631 | WHERE [Year] BETWEEN 2005 AND 2008 632 | GROUP BY BusinessEntityID, [Year] 633 | ORDER BY BusinessEntityID, [Year] 634 | 635 | 46. 636 | 637 | select a.BusinessEntityID,b.JobTitle,c.FirstName,c.LastName,a.Rate * 50 as Bonus 638 | from [HumanResources].[EmployeePayHistory] a join [HumanResources].[Employee] b 639 | on a.BusinessEntityID=b.BusinessEntityID 640 | join [Person].[Person]c 641 | on c.BusinessEntityID=a.BusinessEntityID 642 | where b.SalariedFlag=1 643 | 644 | 47. 645 | select a.BusinessEntityID,a.FirstName+' '+a.LastName+case when a.Suffix is null then '' else ','+ a.Suffix end as fullname, 646 | c.Name as DepartmentName 647 | from [Person].[Person] a join [HumanResources].[EmployeeDepartmentHistory] b 648 | on a.BusinessEntityID=b.BusinessEntityID 649 | join [HumanResources].[Department] c 650 | on c.DepartmentID=b.DepartmentID 651 | where b.ENDDATE IS NULL 652 | order by c.Name,a.FirstName+' '+a.LastName+case when a.Suffix is null then '' else ','+ a.Suffix end 653 | 654 | 48. 655 | SELECT DISTINCT 656 | N1.BusinessEntityID 657 | ,SalesRepLastName = N4.LastName 658 | ,Yr2006StartQuota = N2.SalesQuota 659 | ,Yr2007EndQuota = N3.SalesQuota 660 | ,[%ChangeQuota] = (N3.SalesQuota - N2.SalesQuota) / N2.SalesQuota * 100 661 | FROM Sales.SalesPersonQuotaHistory N1 662 | INNER JOIN Sales.SalesPersonQuotaHistory N2 ON 663 | N1.BusinessEntityID = N2.BusinessEntityID 664 | AND N2.QuotaDate = (SELECT MIN (QuotaDate) 665 | FROM Sales.SalesPersonQuotaHistory 666 | WHERE YEAR (QuotaDate) = 2006) 667 | INNER JOIN Sales.SalesPersonQuotaHistory N3 ON 668 | N1.BusinessEntityID = N3.BusinessEntityID 669 | AND N3.QuotaDate = (SELECT MAX (QuotaDate) 670 | FROM Sales.SalesPersonQuotaHistory 671 | WHERE YEAR (QuotaDate) = 2007) 672 | INNER JOIN Person.Person AS N4 ON N1.BusinessEntityID = N4.BusinessEntityID 673 | 674 | 49. 675 | /* Scrap Rate=Scrap Quantity/Order Quantity ; for orders with Scrap Rate>3% ; WorkOrderID,DueDate,ProductName, 676 | Scrapreason,Scrapped Quantity,Order Quantity,Pct Scrapped */ 677 | 678 | select TOP 10 PERCENT a.WorkOrderID,a.DueDate,c.Name as ProductName,b.Name as ScrapReason,a.ScrappedQty,a.OrderQty,(a.ScrappedQty/CONVERT(FLOAT,a.OrderQty)) * 100 as pct_scrapped 679 | from [Production].[WorkOrder] a left join [Production].[ScrapReason] b 680 | on a.ScrapReasonID=b.ScrapReasonID 681 | left join [Production].[Product] c 682 | on a.ProductID=c.ProductID 683 | where a.ScrappedQty>0 and (a.ScrappedQty/CONVERT(FLOAT,a.OrderQty)) * 100>3 684 | order by a.DueDate DESC 685 | 686 | 50. 687 | select v.ReasonName,v.ReasonType,count(v.SalesOrderID) from 688 | (select a.SalesOrderID,b.Name as ReasonName, 689 | case when COUNT(c.SalesOrderID)>1 then 'Contributing Reason' ELSE 'Exclusion Reason' END as ReasonType 690 | from [Sales].[SalesOrderHeaderSalesReason] a join [Sales].[SalesReason] b 691 | on a.SalesReasonID=b.SalesReasonID 692 | join [Sales].[SalesOrderHeaderSalesReason] c on 693 | a.SalesOrderID=c.SalesOrderID 694 | group by a.SalesOrderID,b.Name) v 695 | group by v.ReasonName,v.ReasonType 696 | 697 | 51. 698 | Part 1 699 | select a.SpecialOfferID,a.Type as DiscType,a.Category,a.Description,a.StartDate,a.EndDate,a.DiscountPct 700 | from [Sales].[SpecialOffer] a 701 | where a.Type='Excess Inventory' and a.Category IN ('Customer','Reseller') 702 | 703 | Part 2 704 | select a.SpecialOfferID,a.Type as DiscType,a.Category,a.Description,a.StartDate,a.EndDate,a.DiscountPct, 705 | count(distinct b.SalesOrderID) as NumOrdersDiscApplied 706 | from [Sales].[SpecialOffer] a left join [Sales].[SalesOrderDetail] b 707 | on a.SpecialOfferID=b.SpecialOfferID 708 | where a.Type='Excess Inventory' and a.Category IN ('Customer','Reseller') 709 | group by a.SpecialOfferID,a.Type,a.Category,a.Description,a.StartDate,a.EndDate,a.DiscountPct 710 | 711 | 52. 712 | select a.BusinessEntityID,max(case when a.Rnk=1 THEN a.Rate END) as LatestPayRate, max(case when a.Rnk=2 then a.Rate else 0 END) as PreviousRate 713 | ,case WHEN max(case when a.Rnk=2 then a.Rate else 0 END) >0 then ((max(case when a.Rnk=1 THEN a.Rate END)- max(case when a.Rnk=2 then a.Rate else 0 END))/ max(case when a.Rnk=2 then a.Rate else 0 END)) * 100 else null end as pct_change 714 | 715 | from 716 | (select a.BusinessEntityID,a.Rate,ROW_NUMBER() over (partition by a.BusinessEntityID order by a.RateChangeDate DESC) as Rnk 717 | from [HumanResources].[EmployeePayHistory] a 718 | ) a 719 | where a.Rnk<3 720 | group by a.BusinessEntityID 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | -------------------------------------------------------------------------------- /SQL Movie Rating Exercise - Stanford.sql: -------------------------------------------------------------------------------- 1 | 2 | Movie ( mID, title, year, director ) 3 | English: There is a movie with ID number mID, a title, a release year, and a director. 4 | 5 | Reviewer ( rID, name ) 6 | English: The reviewer with ID number rID has a certain name. 7 | 8 | Rating ( rID, mID, stars, ratingDate ) 9 | English: The reviewer rID gave the movie mID a number of stars rating (1-5) on a certain ratingDate. 10 | 11 | 1. Find the titles of all movies directed by Steven Spielberg. 12 | 13 | select title from movie 14 | where director='Steven Spielberg' 15 | 16 | 2. Find all years that have a movie that received a rating of 4 or 5, and sort them in increasing order. 17 | 18 | select distinct m.year 19 | from Movie m join Rating r 20 | on m.mID=r.mID 21 | where stars>=4 22 | order by m.year asc 23 | 24 | 3. Find the titles of all movies that have no ratings. 25 | 26 | select m.title 27 | from Movie m left outer join Rating r 28 | on m.mID=r.mID 29 | where r.mID is null 30 | 31 | 4. Some reviewers didn't provide a date with their rating. Find the names of all reviewers who have ratings with a NULL value for the date. 32 | 33 | select distinct r.name 34 | from Reviewer r join Rating X 35 | on r.rID=X.rID 36 | where X.RatingDate is NULL 37 | 38 | 5. Write a query to return the ratings data in a more readable format: reviewer name, movie title, stars, and ratingDate. 39 | Also, sort the data, first by reviewer name, then by movie title, and lastly by number of stars. 40 | 41 | select v.name as Reviewer_Name,m.title,r.stars,r.ratingDate 42 | from Movie m join Rating r 43 | on m.mID=r.mID 44 | join Reviewer v 45 | on v.rID=r.rID 46 | order by v.name,m.title,r.stars 47 | 48 | 6. For all cases where the same reviewer rated the same movie twice and gave it a higher rating the second time, 49 | return the reviewer's name and the title of the movie. 50 | 51 | select distinct b.name,e.title 52 | from Rating a , Reviewer b , Rating c, Reviewer d ,Movie e 53 | where a.rID=b.rID and c.rID=d.rID and a.mID=c.mID and a.rID=c.rID 54 | and c.RatingDate>a.RatingDate and c.stars>a.stars 55 | and a.mID=e.mID 56 | 57 | 7. For each movie that has at least one rating, find the highest number of stars that movie received. 58 | Return the movie title and number of stars. Sort by movie title. 59 | 60 | select a.title,a.highest_rating from 61 | ( 62 | select m.title as title,max(stars) as highest_rating, count(r.rID) as reviews 63 | from Movie m join Rating r 64 | on m.mID=r.mID 65 | group by m.title 66 | having count(r.rID) >= 1 ) a 67 | order by a.title 68 | 69 | 8. For each movie, return the title and the 'rating spread', that is, the difference between highest and lowest ratings given to that movie. 70 | Sort by rating spread from highest to lowest, then by movie title. 71 | 72 | select m.title, max(r.stars) - min(r.stars) as spread 73 | from Movie m join Rating r 74 | on m.mID=r.mID 75 | group by m.title 76 | order by max(r.stars) - min(r.stars) desc,m.title 77 | 78 | 9. Find the difference between the average rating of movies released before 1980 and the average rating of movies released after 1980. 79 | (Make sure to calculate the average rating for each movie, then the average of those averages for movies before 1980 and movies after. 80 | Don't just calculate the overall average rating before and after 1980.) 81 | 82 | select t2.p2-t1.p1 from 83 | (select avg(average) as p1 from 84 | (select g.mid,g.average, year from 85 | (select mid, avg(stars) as average from rating 86 | group by mid) g, movie 87 | where g.mid=movie.mid) j 88 | where year >= 1980) t1, 89 | 90 | (select avg(average) as p2 from 91 | (select g.mid,g.average, year from 92 | (select mid, avg(stars) as average from rating 93 | group by mid) g, movie 94 | where g.mid=movie.mid) j 95 | where year < 1980) t2; 96 | 97 | Advanced Exercises 98 | 99 | 1. Find the names of all reviewers who rated Gone with the Wind. 100 | 101 | select distinct name from Reviewer,Movie,Rating 102 | where (Reviewer.rID=Rating.rID and Rating.mID=Movie.mID) 103 | AND (Movie.title='Gone with the Wind') 104 | 105 | 2. For any rating where the reviewer is the same as the director of the movie, 106 | return the reviewer name, movie title, and number of stars. 107 | 108 | select distinct v.name,m.title,r.stars 109 | from Movie m join Rating r 110 | on m.mID=r.mID 111 | join Reviewer v on 112 | v.rID=r.rID 113 | where m.director=v.name 114 | 115 | 3. Return all reviewer names and movie names together in a single list, alphabetized. 116 | (Sorting by the first name of the reviewer and first word in the title is fine; no need for special processing on last names or removing "The".) 117 | 118 | select distinct name as Names from Reviewer 119 | union 120 | select distinct title as Names from movie 121 | order by Names 122 | 123 | 4. Find the titles of all movies not reviewed by Chris Jackson. 124 | 125 | 126 | select distinct mo.title from Movie mo where mo.mID 127 | NOT IN 128 | (select distinct m.mID from Movie m,Reviewer v,Rating r 129 | where m.mID=r.mID and v.rID=r.rID and v.name='Chris Jackson') 130 | 131 | 5. For all pairs of reviewers such that both reviewers gave a rating to the same movie, return the names of both reviewers. 132 | Eliminate duplicates, don't pair reviewers with themselves, and include each pair only once. For each pair, return the names in the pair in alphabetical order. 133 | 134 | select distinct C.name,D.name 135 | from Rating A, Rating B, Reviewer C, Reviewer D 136 | where (A.mID=B.mID and A.rID<>B.rID) 137 | AND (A.rID=C.rID) 138 | AND (D.rID=B.rID) 139 | AND C.name=3) 169 | 170 | 9. Some directors directed more than one movie. For all such directors, return the titles of all movies directed by them, 171 | along with the director name. Sort by director name, then movie title. 172 | (As an extra challenge, try writing the query both with and without COUNT.) 173 | 174 | select title,director 175 | from movie 176 | where director in 177 | (select director from 178 | (select director,count(distinct mID) 179 | from Movie 180 | group by director 181 | having count(distinct mID)>1)) 182 | order by director,title 183 | 184 | 10. Find the movie(s) with the highest average rating. Return the movie title(s) and average rating. 185 | (Hint: This query is more difficult to write in SQLite than other systems; you might think of it as finding the highest average rating 186 | and then choosing the movie(s) with that average rating.) 187 | 188 | Select m.title,avg(r.stars) 189 | from Movie m join Rating r 190 | on m.mID=r.mID 191 | group by m.title 192 | having avg(r.stars)= 193 | (select max(a.Stars) as HighestRating 194 | from 195 | (select mID, avg(stars) as Stars 196 | from Rating 197 | group by mID) a) 198 | 199 | 11. Find the movie(s) with the lowest average rating. Return the movie title(s) and average rating. 200 | (Hint: This query may be more difficult to write in SQLite than other systems; you might think of it as finding the lowest average rating 201 | and then choosing the movie(s) with that average rating.) 202 | 203 | Select m.title,avg(r.stars) 204 | from Movie m join Rating r 205 | on m.mID=r.mID 206 | group by m.title 207 | having avg(r.stars)= 208 | (select min(a.Stars) as LowestRating 209 | from 210 | (select mID, avg(stars) as Stars 211 | from Rating 212 | group by mID) a) 213 | 214 | 12. For each director, return the director's name together with the title(s) of the movie(s) they directed that received the highest rating among all of their movies, 215 | and the value of that rating. Ignore movies whose director is NULL. 216 | 217 | select director,title,max(stars) as Rating 218 | from Movie,Rating 219 | where Movie.mID=Rating.mID AND (director is NOT NULL) 220 | group by director -------------------------------------------------------------------------------- /Social Network Exercise Stanford.sql: -------------------------------------------------------------------------------- 1 | --Students at your hometown high school have decided to organize their social network using databases. 2 | --So far, they have collected information about sixteen students in four grades, 9-12. Here's the schema: 3 | 4 | --Highschooler ( ID, name, grade ) 5 | --English: There is a high school student with unique ID and a given first name in a certain grade. 6 | 7 | --Friend ( ID1, ID2 ) 8 | --English: The student with ID1 is friends with the student with ID2. Friendship is mutual, so if (123, 456) is in the Friend table, so is (456, 123). 9 | 10 | --Likes ( ID1, ID2 ) 11 | --English: The student with ID1 likes the student with ID2. Liking someone is not necessarily mutual, so if (123, 456) is in the Likes table, 12 | -- there is no guarantee that (456, 123) is also present. 13 | 14 | --1.Find the names of all students who are friends with someone named Gabriel 15 | 16 | select distinct name from Highschooler 17 | where ID in 18 | (select ID2 19 | from Friend 20 | where ID1 in 21 | (select ID 22 | from Highschooler 23 | where name='Gabriel') 24 | UNION 25 | select ID1 26 | from Friend 27 | where ID2 in 28 | (select ID 29 | from Highschooler 30 | where name='Gabriel')) 31 | 32 | --2. For every student who likes someone 2 or more grades younger than themselves, return that student's name and grade, 33 | --and the name and grade of the student they like. 34 | 35 | select distinct b.name,b.grade,c.name,c.grade 36 | from Likes a join Highschooler b 37 | on a.ID1=b.ID 38 | join Highschooler c 39 | on a.ID2=c.ID 40 | where b.grade-c.grade>=2 41 | 42 | --3. For every pair of students who both like each other, return the name and grade of both students. 43 | --Include each pair only once, with the two names in alphabetical order. 44 | 45 | select distinct h1.name, h1.grade, h2.name, h2.grade 46 | from Likes l1, Likes l2, Highschooler h1, Highschooler h2 47 | where l1.ID1=l2.ID2 and l2.ID1=l1.ID2 and l1.ID1=h1.ID and l1.ID2=h2.ID and h1.name H2.grade) 76 | order by grade, name; 77 | 78 | --7. For each student A who likes a student B where the two are not friends, find if they have a friend C in common (who can introduce them!). 79 | --For all such trios, return the name and grade of A, B, and C. 80 | 81 | Select h1.name,h1.grade,h2.name,h2.grade,h3.name,h3.grade 82 | From Highschooler h1,Highschooler h2,Highschooler h3,Likes L 83 | Where h1.ID = L.ID1 AND h2.ID = L.ID2 84 | and 85 | L.ID1 not in (Select ID1 FROM Friend where (ID1=h1.ID and ID2=h2.ID) OR (ID1=h2.ID and ID2=h1.ID) ) 86 | AND h3.ID in 87 | ( 88 | Select F1.ID2 from Friend F1,Friend F2 89 | where 90 | ((F1.ID1=h1.ID AND F1.ID2 = h3.ID) 91 | OR (F1.ID1=h3.ID AND F1.ID2 = h1.ID )) 92 | AND 93 | ((F2.ID1=h2.ID AND F2.ID2 = h3.ID ) 94 | OR (F2.ID1=h3.ID AND F2.ID2 = h2.ID)) 95 | ) 96 | 97 | --8. Find the difference between the number of students in the school and the number of different first names. 98 | 99 | select count(distinct ID) - count(distinct name) from Highschooler 100 | 101 | --Extra Questions - Advanced 102 | 103 | --1.For every situation where student A likes student B, but student B likes a different student C, return the names and grades of A, B, and C. 104 | 105 | select a.name,a.grade,b.name,b.grade,c.name,c.grade 106 | from Highschooler a, Highschooler b,Highschooler c,Likes d,Likes e 107 | where (a.ID=d.ID1 and b.ID=d.ID2) and (b.ID<>d.ID1 and a.ID<>d.ID2) 108 | and (b.ID=e.ID1 and c.ID=e.ID2) and (a.name<>b.name) 109 | and (b.name<>c.name) and (c.anme<>a.name) 110 | 111 | --2. Find those students for whom all of their friends are in different grades from themselves. Return the students' names and grades. 112 | 113 | select distinct name, grade from Highschooler 114 | where ID not in ( 115 | select ID1 116 | from Highschooler H1, Friend, Highschooler H2 117 | where H1.ID = Friend.ID1 and Friend.ID2 = H2.ID and H1.grade = H2.grade) 118 | 119 | --3. What is the average number of friends per student? (Your result should be just one number.) 120 | 121 | select avg(cnt) from( 122 | select id1,count(id2) as cnt from friend 123 | group by id1) 124 | 125 | --4. Find the number of students who are either friends with Cassandra or are friends of friends of Cassandra. 126 | --Do not count Cassandra, even though technically she is a friend of a friend 127 | 128 | select count(id2) from friend where id1 in 129 | ( 130 | select id2 from friend where id1 in (select id from highschooler where name='Cassandra') 131 | ) 132 | and id1 not in (select id from highschooler where name='Cassandra') 133 | 134 | --5. Find the name and grade of the student(s) with the greatest number of friends. 135 | 136 | 137 | select h.name, h.grade from highschooler h, friend f where 138 | h.id = f.id1 group by f.id1 having count(f.id2) = ( 139 | select max(r.c) from 140 | (select count(id2) as c from friend group by id1) as r) 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /Student Faculty SQL Exercise.sql: -------------------------------------------------------------------------------- 1 | --Student(snum, sname, major, level, age) 2 | --Class(name, meets at, room, fid) 3 | --Enrolled(snum, cname) 4 | --Faculty(fid, fname, deptid) 5 | 6 | --1. Find the names of all Juniors (Level = JR) who are enrolled in a class taught by I. Teach. 7 | 8 | select distinct s.sname 9 | from Student s join Enrolled e 10 | on s.snum=e.snum 11 | join Class c 12 | on e.cname=c.name 13 | join Faculty f 14 | on c.fid=e.fid 15 | where f.fname='I.Teach' and s.level='JR' 16 | 17 | --2. Find the age of the oldest student who is either a History major or is enrolled in a course taught by I. Teach 18 | 19 | select max(s.age) as Max_Age 20 | from Student s join Enrolled e 21 | on s.snum=e.snum 22 | join Class c 23 | on e.cname=c.name 24 | join Faculty f 25 | on c.fid=e.fid 26 | where f.fname='I.Teach' or s.major='History' 27 | 28 | --3. Find the names of all classes that either meet in room R128 or have five or more students enrolled. 29 | 30 | select distinct c.name as Class_name 31 | from Class c 32 | where c.room='R128' 33 | UNION 34 | select a.name as Class_name from 35 | (select c.name,count(distinct c.snum) as students_enrolled 36 | join Enrolled e join Class c 37 | on c.name=e.cname 38 | group by c.name 39 | having count(distinct c.snum)>=5)a 40 | 41 | --4. Find the names of all students who are enrolled in two classes that meet at the same time 42 | 43 | select distinct x.sname from 44 | (select s.sname,a.meetsat,count(distinct b.cname) 45 | from Class a join Enrolled b 46 | on a.cname=b.name 47 | join Student s 48 | on s.snum=b.snum 49 | group by a.sname,a.meetsat 50 | having count(distinct b.cname)>=2 ) x 51 | 52 | --5. Find the names of faculty members who teach in every room in which some class is taught 53 | 54 | select distinct x.fname as faculty from 55 | (select f.fname,count(distinct c.room) as rooms 56 | Faculty f join Class c 57 | on f.fid=c.fid 58 | group by f.fname 59 | having count(distinct c.room)=(select count(distinct room) from class)) x 60 | 61 | --6. Find the names of faculty members for whom the combined enrollment of the courses that they teach is less than five 62 | 63 | select distinct x.fname as Faculty 64 | (select f.fname,count(distinct e.snum) 65 | from Faculty f join Class c 66 | on f.fid=c.fid 67 | join Enrolled e 68 | on e.cname=c.cname 69 | group by f.fname 70 | having count(distinct e.snum)<5 ) x 71 | 72 | --7. Print the Level and the average age of students for that Level, for each Level 73 | 74 | select Level,AVG(age) 75 | from Student 76 | group by Level 77 | 78 | --8. Print the Level and the average age of students for that Level, for all Levels except JR 79 | 80 | select Level,AVG(age) 81 | from Student 82 | where Level<>'JR' 83 | group by Level 84 | 85 | --9. Find the names of students who are enrolled in the maximum number of classes 86 | 87 | select distinct y.sname from 88 | (select x.sname,max(x.classes) from 89 | (select s.sname,count(distinct e.cname) as classes 90 | from Class c join Enrolled e 91 | on c.name=e.cname 92 | join Student s 93 | on s.snum=e.snum 94 | group by s.name) x )y 95 | 96 | --10. Find the names of students who are not enrolled in any class 97 | 98 | select distinct s.sname 99 | from Student s 100 | where s.snum NOT IN 101 | (select distinct e.snum from Enrolled e) 102 | 103 | --11. For each age value that appears in Students, find the level value that appears most often. For example, if there are more FR level students aged 18 than SR, 104 | --JR, or SO students aged 18, you should print the pair (18, FR) 105 | 106 | select x.age,x.level from 107 | (select age,level,row_number() over (partition by age order by count(*) desc) as Ranking 108 | from Student )x 109 | where x.Ranking =1 --------------------------------------------------------------------------------