ElenaR1

SQL EX 4-5 (12-18,19-25,26-1)

Mar 19th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MySQL 29.02 KB | None | 0 0
  1. --EXERCISE 4
  2. --EX 4
  3.  
  4. --moe
  5.  
  6. SELECT *
  7. FROM CLASSES,ships
  8. where CLASSES.class=ships.CLASS
  9. --sushtoto kato gornoto
  10. select c.*,s.*,o.*
  11. from ships s
  12. join CLASSES c on s.class=c.CLASS
  13. join OUTCOMES o on s.NAME=o.SHIP
  14.  
  15. SELECT *
  16. FROM CLASSES
  17.       JOIN SHIPS ON CLASSES.CLASS = SHIPS.CLASS--ne pokazva tezi za koito nqma suvpadashti klasove
  18.  
  19. SELECT *
  20. FROM CLASSES
  21.     LEFT OUTER JOIN SHIPS ON CLASSES.CLASS = SHIPS.CLASS--na tezi koito nqmat suvpadashti klasove im pishe null
  22.     LEFT OUTER JOIN OUTCOMES ON SHIPS.NAME = OUTCOMES.SHIP
  23.  
  24.  
  25.  
  26.  
  27.  
  28. -- пример за full join
  29. -- за всеки актьор и/или продуцент да се изведе
  30. -- името му, рождената му дата и networth
  31. use movies;
  32. --moe nishto ne pokazva zashtoto nikoi movieexec ne suvpada s moviestar
  33. select ms.name, me.name, ms.birthdate, me.networth
  34. from moviestar ms
  35. join movieexec me on ms.name = me.name;
  36.  
  37. -- неудобен начин:
  38. select ms.name, me.name, ms.birthdate, me.networth
  39. from moviestar ms
  40. full join movieexec me on ms.name = me.name;
  41. -- хубав начин:
  42. select coalesce(ms.name, me.name) as name, ms.birthdate, me.networth
  43. from moviestar ms
  44. full join movieexec me on ms.name = me.name;
  45.  
  46. -- 1.1.
  47. select title, year, name, address
  48. from movie
  49. join studio on studioname = name
  50. where length > 120;
  51.  
  52. --ili:
  53. select title,year,s.name,s.address
  54. from movie
  55. where LENGTH>120 and studioname in (select name from studio s)
  56.  
  57. -- 1.2.
  58. --moe
  59. select m.*,s.*
  60. from movie m ,starsin s
  61.  
  62. --istinsko
  63. select distinct studioname, starname
  64. from movie
  65. join starsin on title = movietitle and year = movieyear
  66. order by studioname;
  67. --
  68. --1.3
  69. -- ot tuk nagledno vijdame che harrison ford uchastva samo v empire strikes back i star wars s
  70. --producer#=555 koito v moviexec suvpada s George Lucas; distinct polzvame za da ne se povtarq george lucas 2
  71. --puti za 2ta filma
  72. select *
  73. from movieexec
  74. select*
  75. from movie
  76. select *
  77. from starsin
  78.  
  79. select distinct name
  80. from movieexec me
  81. join movie m on PRODUCERC#=CERT#--GRESHNO: me.cert#=m.producer#
  82. join starsin s on title=movietitle
  83. where starname='Harrison Ford'
  84.  
  85. --1.4
  86. select * from starsin
  87. select * from movie
  88.  
  89. select starname
  90. from starsin
  91. join moviestar on name=STARNAME
  92. join movie m on movietitle=title
  93.  where studioname ='MGM' and gender='F'
  94.  
  95.  --1.5
  96.  select * from MOVIEEXEC
  97.  select * from movie
  98.  
  99.  select name,title
  100.  from movieexec me
  101.  join movie on PRODUCERC#=CERT#
  102.  where name in (select name from MOVIEEXEC where CERT# in( select PRODUCERC#
  103.  from movie where title='Gone With the Wind'))
  104.  
  105. -- 1.6. Всички актьори, които не са играли във филми
  106. -- (т.е. нямаме информация в кои филми са играли)
  107. select * from starsin
  108. select * from moviestar
  109.  
  110. select *
  111. from moviestar
  112. left join starsin on name = starname
  113.  
  114. --oficialno
  115. select name
  116. from moviestar
  117. left join starsin on name = starname
  118. where starname is null;
  119. -- OR:
  120. select name
  121. from moviestar
  122. where name not in (select starname from starsin);
  123.  
  124. -- 2.1.
  125. use pc;
  126.  
  127. select maker, p.model, type
  128. from product p
  129. left join  (select model from pc
  130.             union all
  131.             select model from laptop
  132.             union all
  133.             select model from printer) t
  134.     on p.model = t.model
  135. where t.model is null;
  136. -- OR:
  137. select maker, model, type
  138. from product
  139. where model not in (select model from pc)
  140.     and model not in (select model from laptop)
  141.     and model not in (select model from printer);
  142.  
  143. use ships;
  144. --3.1
  145. select * from ships,CLASSES
  146. --select * from ships where class='Bismarck'
  147.  
  148. select name,ships.class,country,bore,launched
  149. from ships
  150. join CLASSES c on ships.class=c.class
  151.  
  152.  
  153. -- 3.3.
  154. select distinct ship
  155. from outcomes
  156. join battles on battle=name
  157. where year(date) = 1942;
  158.  
  159. -- 3.4.
  160. select country, name
  161. from classes
  162. join ships on classes.class = ships.class
  163. left join outcomes on name = ship
  164. where outcomes.ship is null;
  165. -- OR:
  166. select country, name
  167. from outcomes
  168. right join ships on ship = name
  169. join classes on classes.class = ships.class
  170. where outcomes.ship is null;
  171.  
  172. --moe
  173. select * from ships
  174. select * from CLASSES
  175. select * from OUTCOMES
  176.  
  177. select *
  178. from ships s
  179. join classes c on s.class=c.class
  180. full join outcomes o on name=ship
  181. where battle is NULL
  182.  
  183.  
  184. -- За всеки клас британски кораби да се изведат
  185. -- имената им (на класовете) и имената на всички битки,
  186. -- в които са участвали кораби от този клас.
  187. -- Ако даден клас няма кораби или има, но те не са
  188. -- участвали в битка, също да се изведат (със стойност
  189. -- NULL за име на битката).
  190.  
  191. --moe
  192. select * from ships
  193. select * from CLASSES order by country
  194. select * from OUTCOMES order by ship
  195.  
  196. select c.class,ship,battle
  197. from classes c
  198. join ships s on s.class=c.class
  199. full join outcomes o on name=ship
  200. where country ='Gt.Britain'
  201.  
  202. --oficialno
  203. select distinct classes.class, battle
  204. from outcomes
  205. join ships on ship = name
  206. right join classes on ships.class = classes.class
  207. where country = 'Gt.Britain';
  208.  
  209. -- нека пробваме да "обърнем" заявката, както направихме в 3.4:
  210. -- грешно:
  211. select distinct classes.class, battle
  212. from classes
  213. left join ships on classes.class = ships.class
  214. join outcomes on name = ship
  215. where country = 'Gt.Britain';
  216.  
  217. -- все още е грешно:
  218. select distinct classes.class, battle
  219. from classes
  220. left join ships on classes.class = ships.class
  221. left join outcomes on ship = name
  222. where country = 'Gt.Britain';
  223.  
  224. -- Когато в една заявка има повече от един join
  225. -- и поне един от тях е outer join, редът на join-ване
  226. -- има значение. Ако са само inner join - няма.
  227.  
  228. -- ако държим на left join, може така:
  229. select distinct classes.class, battle
  230. from classes
  231. left join (select *
  232.             from ships
  233.             join outcomes on ship = name) t
  234.                 on classes.class = t.class
  235. where country = 'Gt.Britain';
  236.  
  237.  
  238. -- важен пример: при outer join има разлика дали
  239. -- дадено условие ще бъде в ON или WHERE (при inner
  240. -- няма, понеже се свежда до подмножество на декартово
  241. -- произведение):
  242.  
  243. -- За всеки клас да се изведат името му, държавата
  244. -- и имената на всички негови кораби, пуснати през 1916 г.
  245. select classes.class, country, name
  246. from classes
  247. join ships on classes.class = ships.class
  248. where launched = 1916;
  249.  
  250. -- може да се напише и така, макар и безсмислено:
  251. select classes.class, country, name
  252. from classes
  253. join ships
  254.     on classes.class = ships.class and launched = 1916;
  255.  
  256. -- Да допълним горната задача, като добавим и класовете,
  257. -- които нямат нито един кораб от 1916 - с/у тях да
  258. -- пише NULL.
  259.  
  260. -- грешно:
  261. select classes.class, country, name
  262. from classes
  263. left join ships on classes.class = ships.class
  264. where launched = 1916;
  265. --moe greshno
  266. select *
  267. from classes
  268. full join ships on classes.class = ships.class
  269. where launched = 1916;
  270. -- изпускаме например класовете, които нямат кораби
  271. -- при тях launched има стойност null
  272.  
  273. -- все още грешно:
  274. select classes.class, country, name
  275. from classes
  276. left join ships on classes.class = ships.class
  277. where launched = 1916 or launched is null;
  278.  
  279. -- липсват класове, които имат кораби, но нито един
  280. -- от тези кораби не е от 1916
  281.  
  282. -- друг проблем: хващаме излишни редове, ако
  283. -- launched по принцип позволява null
  284.  
  285. -- вярно:
  286. select classes.class, country, name
  287. from classes
  288. left join ships
  289.     on classes.class = ships.class and launched = 1916;
  290.  
  291. -- друго вярно, макар и излишно усложнено:
  292. select classes.class, country, name
  293. from classes
  294. left join (select *
  295.             from ships
  296.             where launched = 1916) ships1916
  297. on classes.class = ships1916.class;
  298.  
  299.  
  300.  
  301. -- Общи задачи
  302.  
  303. use movies;
  304. --1
  305. -- Да се изведат заглавията и годините на всички филми, чието заглавие
  306. -- съдържа едновременно като поднизове "the" и "w" (не непременно в този ред).
  307. -- Резултатът да бъде сортиран по година (първо най-новите), а филми от
  308. -- една и съща година да бъдат подредени по азбучен ред.
  309. select title, year
  310. from movie
  311. where title like '%the%' and title like '%w%'
  312. order by year desc, title;
  313.  
  314. use ships;
  315. --2
  316. -- Държавите, които имат класове с различен калибър (bore)
  317. -- (напр. САЩ имат клас с bore=14 и класове с bore=16,
  318. -- докато Великобритания има само класове с 15)
  319. select distinct c1.country
  320. from classes c1
  321. join classes c2 on c1.country = c2.country
  322. where c1.bore <> c2.bore;
  323. -- оптимизация: c1.bore < c2.bore - ще улесни работата на distinct по-горе
  324. --ili moe:
  325.  
  326. select country
  327. from classes c1
  328. where bore not in (select bore from classes c2 where c2.country!=c1.COUNTRY)
  329.  
  330. use pc;
  331. --3
  332. -- Компютрите, които са по-евтини от всеки лаптоп
  333. -- и принтер на същия производител
  334. select pc.*
  335. from pc
  336. join product p on pc.model = p.model
  337. where price < all (select price
  338.                     from laptop
  339.                     join product p1 on laptop.model=p1.model
  340.                     where p1.maker = p.maker)
  341.     and price < all (select price
  342.                     from printer
  343.                     join product p1 on printer.model=p1.model
  344.                     where p1.maker = p.maker);
  345. -- ако подзаявката върне празен списък, условието
  346. -- price < all (...) ще бъде true
  347.  
  348.  
  349.  
  350. use ships;
  351. --4
  352. -- Имената на всички кораби, за които едновременно са изпълнени следните
  353. -- условия:
  354. -- (1) участвали са в поне една битка и
  355. -- (2) имената им (на корабите) започват с C или K.
  356. select distinct ship
  357. from outcomes
  358. where ship like 'C%' or ship like 'K%';
  359.  
  360. --5
  361. -- Името, държавата и калибъра (bore) на всички класове кораби с 6, 8 или 10
  362. -- оръдия. Калибърът да се изведе в сантиметри (1 инч е приблизително 2.54 см).
  363. select class, country, bore * 2.54 as bore_cm
  364. from classes
  365. where numguns in (6, 8, 10);
  366.  
  367. --6
  368. -- (От държавен изпит)
  369. -- Имената на класовете, за които няма кораб, пуснат на вода (launched) след
  370. -- 1921 г. Ако за класа няма пуснат никакъв кораб, той също трябва да излезе
  371. -- в резултата.
  372.  
  373. -- грешно:
  374. select distinct class
  375. from ships
  376. where launched <= 1921;
  377.  
  378. -- вярно:--tezi koito ne sa launch-nati prez 1921 gi nqma v tablicata ships, a gi ima samo v classes
  379. select class
  380. from classes
  381. where class not in (select class from ships where launched > 1921);
  382.  
  383. -- вярно:
  384. SELECT c.class
  385. FROM classes c
  386. WHERE NOT EXISTS (SELECT 1
  387.                 FROM ships t
  388.                 WHERE t.class=c.class
  389.                     AND t.launched > 1921);
  390. --moe
  391. select classes.*,s.*
  392. from classes
  393. left join ships s on classes.class = s.class and launched > 1921
  394.  
  395. -- вярно:
  396. select classes.class
  397. from classes
  398. left join ships on classes.class = ships.class and launched > 1921
  399. where name is null;
  400.  
  401.  
  402.  
  403. select *
  404. from MovieExec m1, Movie m2
  405. where m1.CERT#=m2.PRODUCERC#
  406.  
  407.  
  408. select *
  409. from MovieExec m1 join Movie m2
  410. on m1.CERT#=m2.PRODUCERC#
  411.  
  412.  
  413. select *
  414. from MovieExec m1 inner JOIN Movie m2
  415. ON m1.CERT#=m2.PRODUCERC#
  416.  
  417. select *
  418. from MovieExec m1 LEFT OUTER JOIN Movie m2
  419. ON m1.CERT#=m2.PRODUCERC#
  420.  
  421. select *
  422. from MovieExec m1 RIGHT  JOIN Movie m2
  423. ON m1.CERT#=m2.PRODUCERC#
  424.  
  425. select *
  426. from MovieExec CROSS JOIN Movie
  427.  
  428.  
  429. SELECT AVG (netWorth)
  430. FROM MovieExec
  431.  
  432. SELECT COUNT(*)
  433. FROM StarsIn
  434.  
  435. SELECT COUNT(DISTINCT starName)
  436. FROM StarsIn
  437.  
  438. SELECT MAX(Quantity * UnitPrice * (1 - Discount))
  439. FROM "Order Details"
  440.  
  441.  
  442. SELECT studioName, SUM(length)
  443. FROM Movie
  444. GROUP BY studioName
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.                                                             --EXERCISE 5
  452. --EXERCISE 5
  453. use movies;
  454.  
  455. SELECT AVG(netWorth)
  456. FROM MovieExec;
  457.  
  458. SELECT COUNT(*)
  459. FROM StarsIn;
  460.  
  461. SELECT COUNT(DISTINCT starName)
  462. FROM StarsIn;
  463.  
  464. select count(*), count(distinct starName)
  465. from StarsIn;
  466.  
  467.  
  468. SELECT studioName, SUM(length)
  469. FROM Movie
  470. GROUP BY studioName;
  471.  
  472. -- ако нямаше GROUP BY, можеше така:
  473. select distinct studioname, (select sum(length)
  474.                              from movie
  475.                              where studioname = m.studioname)
  476. from movie m;
  477.  
  478. -- най-дългият филм (ако са повече от един, да се
  479. -- изведат всички):
  480. -- грешно:
  481. select *
  482. from movie
  483. where length = max(length);
  484. -- вярно:
  485. select *
  486. from movie
  487.  
  488. select *
  489. from movie
  490. where length = (select max(length) from movie);
  491. --NE RABOTI
  492. USE movies
  493. select TITLE
  494. from movie
  495. where length >= ALL(select length from movie)
  496.  
  497.  
  498. -- Групиране по израз:
  499. -- За всяка година да се изведе колко филмови
  500. -- звезди са родени
  501. select year(birthdate), count(*)
  502. from moviestar
  503. group by year(birthdate);
  504.  
  505. -- доказателство за реда, в който се изпълняват клаузите:
  506. -- следната заявка е грешна:
  507. select title as movietitle
  508. from movie
  509. where movietitle like 'Star %';
  510. -- movietitle не е дефинирано
  511.  
  512. -- за всяка филмова звезда - броят на филмите, в които
  513. -- се е снимала
  514. -- ако за дадена звезда не знаем какви филми има,
  515. -- за нея да се изведе 0
  516. --MOE
  517. select * from STARSIN
  518.  
  519. select STARNAME,COUNT(*)
  520. FROM STARSIN
  521. GROUP BY (STARNAME)
  522. --OFICIALNO
  523. select name, count(starname) as moviesCount
  524. from moviestar
  525. left join starsin on name = starname
  526. group by name;
  527.  
  528. -- още за null:
  529. select *
  530. from movie
  531. where length = (select max(length) from movie);
  532. -- горното намира най-дългите филми измежду тези,
  533. -- за които дължината е известна
  534. select *
  535. from movie
  536. where length >= all (select length from movie);
  537. -- горното не връща нищо, ако има филми с неизвестна
  538. -- дължина
  539.  
  540. -- не може avg(count( и др. подобни, да не се смесват!
  541. -- пример: да се изведе средният брой филми, в
  542. -- които са се снимали актьорите
  543. -- грешно:
  544. -- select avg(count(...)) from ...
  545. -- вярно:
  546. select avg(moviescount)
  547. -- или по-добре: select avg(convert(real, moviescount))
  548. from (select count(movietitle) as moviescount
  549.     from moviestar
  550.     left join starsin on name = starname
  551.     group by name) stat;
  552.  
  553. -- having може само ако има преди него group by
  554.  
  555. -- често срещана грешка:
  556. select *
  557. from movie
  558. where length = max(select length from movie);
  559.  
  560. -------------------------
  561.  
  562. use pc;
  563. -- 1.1.
  564. select avg(speed)
  565. from pc;
  566.  
  567. -- 1.2.
  568. select maker, avg(screen)
  569. from laptop
  570. join product on laptop.model = product.model
  571. group by maker;
  572.  
  573. -- 1.3.
  574. select avg(speed)
  575. from laptop
  576. where price > 1000;
  577.  
  578. --TOVA E NA CENITE > 1000 PO OTDELNO
  579.  
  580. select PRICE,AVG(SPEED)
  581. FROM LAPTOP
  582. WHERE PRICE > 1000
  583. GROUP BY PRICE
  584.  
  585. --1.4
  586. select AVG(PRICE)
  587. FROM PC
  588. JOIN PRODUCT P ON PC.MODEL=P.MODEL
  589. WHERE MAKER='A'
  590.  
  591. -- 1.5.
  592. select avg(price)
  593. from
  594. (
  595.     select price
  596.     from product p join pc
  597.     on p.model=pc.model
  598.     where maker='B'
  599.  
  600.     union all
  601.  
  602.     select price
  603.     from product p join laptop l
  604.     on p.model=l.model
  605.     where maker='B'
  606. ) AllPrices;
  607.  
  608. -- 1.6.
  609. SELECT * FROM PC
  610.  
  611. select speed, avg(price)
  612. from pc
  613. group by speed;
  614.  
  615. -- 1.7.
  616. select maker
  617. from product
  618. where type='PC'
  619. group by maker
  620. having count(*) >= 3;
  621.  
  622. -- 1.8.
  623.  
  624. SELECT * FROM PRODUCT P
  625. JOIN PC ON P.MODEL=PC.MODEL
  626. -
  627. select distinct maker
  628. from product
  629. join pc on product.model = pc.model
  630. where price = (select max(price) from pc);
  631.  
  632. -- 1.9.
  633. select speed, avg(price)
  634. from pc
  635. where speed > 800
  636. group by speed;
  637. -- тук може и с having, но няма да е по-яко
  638.  
  639. -- 1.10.
  640. select avg(hd)
  641. from pc
  642. join product p on p.model=pc.model
  643. where maker in
  644.     (select maker
  645.     from product
  646.     where type='Printer');
  647.  
  648. -- 1.11.
  649. select screen, max(price) - min(price)
  650. from laptop
  651. group by screen;
  652.  
  653. use ships;
  654. -- 2.1.
  655. select * from classes
  656.  
  657. select count(*)
  658. from classes;
  659.  
  660. --vseki klas kolko koraba ima
  661. select * from ships
  662. order by class
  663.  
  664. select class,count(*)
  665. from  ships
  666. group by class
  667.  
  668. -- 2.2.
  669. select *
  670. from classes c
  671. join ships s on c.class = s.class;
  672.  
  673. select avg(numguns)
  674. from classes c
  675. join ships s on c.class = s.class;
  676.  
  677. -- 2.3.
  678. select * from ships
  679. select class
  680.  from ships
  681. group by class
  682.  
  683. select class, min(launched) as FirstYear,
  684.             max(launched) as LastYear
  685. from ships
  686. group by class;
  687.  
  688. -- 2.4. (не се включват класове без
  689. -- потънали кораби)
  690. select *
  691. from ships s
  692. join outcomes o on s.name=o.ship
  693. where o.result='sunk'
  694. order by class
  695.  
  696. select class, count(*)
  697. from ships s
  698. join outcomes o on s.name=o.ship
  699. where o.result='sunk'
  700. group by class;
  701.  
  702. -- 2.5.
  703. select * from ships order by class
  704.  
  705. select class
  706.         from ships
  707.         group by class
  708.         having count(*)>4
  709.  
  710. select class, count (name)
  711. from ships s
  712. join outcomes o on s.name=o.ship
  713. where class in
  714.         (select class
  715.         from ships
  716.         group by class
  717.         having count(*)>4)
  718. group by class;
  719.  
  720. select class, count (name)
  721. from ships s
  722. join outcomes o on s.name=o.ship
  723. where result='sunk' and class in
  724.         (select class
  725.         from ships
  726.         group by class
  727.         having count(*)>4)
  728. group by class;
  729.  
  730. --2.6
  731. select * from CLASSES
  732.  
  733. select country, avg(displacement)
  734. from CLASSES
  735. group by COUNTRY
  736.  
  737. -------------------------
  738. -- Задачи - 2
  739.  
  740. use movies;
  741. -- 1. За всеки актьор/актриса изведете броя на
  742. -- различните студиа, с които са записвали филми.
  743. select starname, count(distinct studioname)
  744. from starsin
  745. join movie on movietitle=title and movieyear=year
  746. group by starname;
  747.  
  748. -- 2. За всеки актьор/актриса изведете броя на
  749. -- различните студиа, с които са записвали филми,
  750. -- включително и за тези, за които нямаме информация в
  751. -- кои филми са играли.
  752. select name, count(distinct studioname)
  753. from movie
  754. join starsin on movietitle=title and movieyear=year
  755. right join moviestar on name=starname
  756. group by name;
  757.  
  758. -- OR:
  759. select name, count(distinct studioname)
  760. from moviestar
  761. left join starsin on name=starname
  762. left join movie on movietitle=title and movieyear=year
  763. group by name;
  764.  
  765. -- 3. Изведете имената на актьорите, участвали в поне
  766. -- три филма след 1990 г.
  767. select starname
  768. from starsin
  769. where movieyear>1990
  770. group by starname
  771. having count(*)>=3;
  772.  
  773. use pc;
  774. -- 4. Да се изведат различните модели компютри,
  775. -- подредени по цена на най-скъпия конкретен компютър
  776. -- от даден модел.
  777. select * from pc order by model
  778.  
  779. select model,max(price)
  780. from pc
  781. group by model
  782. order by max(price);
  783.  
  784.  
  785. -- 5. Изведете броя на потъналите американски кораби за
  786. -- всяка проведена битка с поне един потънал американски
  787. -- кораб.
  788. select *
  789. from outcomes
  790. join ships s on name=ship
  791. join classes c on s.class=c.class
  792. where country='USA'
  793.  
  794. use ships;
  795. --OFICIALNO
  796. select battle, count(*)
  797. from outcomes
  798. join ships on ship = name
  799. join classes on ships.class = classes.class
  800. where result = 'sunk' and country = 'USA'
  801. group by battle;
  802.  
  803. -- 6. Битките, в които са участвали поне 3 кораба на
  804. -- една и съща страна.
  805. select distinct battle
  806. from outcomes
  807. join ships on ship = name
  808. join classes on ships.class = classes.class
  809. group by battle, country
  810. having count(*) >= 3;
  811. -- distinct, понеже в една битка може да има примерно 4 кораба от САЩ и 4 кораба от Япония
  812.  
  813. -- За всеки клас да се изведе името му, държавата и първата година,
  814. -- в която е пуснат кораб от този клас
  815. select c.class, country, min(launched) as FirstYear
  816. from classes c
  817. join ships s on c.class = s.class
  818. group by c.class, country;
  819. -- или:
  820. -- select c.class, min(country) as country, min(launched) as firstYear
  821. -- from classes c
  822. -- join ships on c.class = ships.class
  823. -- group by c.class;
  824.  
  825. -- За всеки клас с кораби - името на класа, името на произволен кораб и брой кораби
  826. select class, min(name), count(*)
  827. from ships
  828. group by class;
  829.  
  830. -- 7. Имената на класовете, за които няма кораб, пуснат
  831. -- на вода след 1921 г., но имат пуснат поне един кораб.
  832. select * from ships order by class
  833.  
  834. SELECT class
  835. FROM ships
  836. GROUP BY class
  837. HAVING MAX(launched) <= 1921;
  838.  
  839. -- 8. За всеки кораб да се изведе броят на битките, в които е бил увреден.
  840. -- Ако корабът не е участвал в битки или пък никога не е бил
  841. -- увреждан, в резултата да се вписва 0.
  842.  
  843. -- грешно (за справка - упражнение 4):
  844. select name, count(battle)
  845. from ships
  846. left join outcomes on name = ship
  847. where result = 'damaged' or result is null
  848. group by name;
  849. -- губим корабите, които са участвали в битки, но не са били damaged
  850.  
  851. -- вярно:
  852. select name, count(battle)
  853. from ships
  854. left join outcomes on name = ship and result = 'damaged'
  855. group by name;
  856.  
  857. -- или (вярно):
  858.  
  859. ... left join (select * from outcomes where result = 'damaged') d ...
  860.  
  861. -- или (дава възможности за много сложни заявки):
  862.  
  863. select name, (select count(*)
  864.     from outcomes o
  865.     where result = 'damaged'
  866.         and o.ship = s.name)
  867. from ships s;
  868.  
  869. -- 8.1. За всяка държава да се изведе броят на корабите и броят на
  870. -- потъналите кораби.
  871. -- Всяка от бройките може да бъде и нула.
  872. select country, count(ships.name), count(outcomes.ship)
  873. from classes
  874. left join ships on classes.class = ships.class
  875. left join outcomes on name = ship and result = 'sunk'
  876. group by country;
  877. -- понеже един кораб потъва най-много веднъж, няма нужда от count(distinct name)
  878.  
  879. -- 8.2. За всяка държава да се изведе броят на повредените кораби и броят на потъналите кораби.
  880. -- Всяка от бройките може да бъде и нула.
  881. select country, count(distinct damaged.ship) as damaged, count(distinct sunk.ship) as sunk
  882. from classes
  883. left join ships on classes.class = ships.class
  884. left join outcomes damaged on name = damaged.ship and damaged.result = 'damaged'
  885. left join outcomes sunk on name = sunk.ship and sunk.result = 'sunk'
  886. group by country;
  887. -- distinct е нужен, понеже заради декартовите произведения при join-овете един запис може да се дублира...
  888. -- напр. ако кораб е бил два пъти damaged и веднъж sunk, ще има два реда в sunk.*, в които ще се споменава същият кораб
  889.  
  890. -- по-добре:
  891. select country, (select count(distinct name)
  892.                 from classes
  893.                 join ships on classes.class = ships.class
  894.                 join outcomes on ship = name
  895.                 where result = 'damaged'
  896.                     and country = c.country) as damaged,
  897.                 (select count(*)
  898.                 from classes
  899.                 join ships on classes.class = ships.class
  900.                 join outcomes on ship = name
  901.                 where result = 'sunk'
  902.                     and country = c.country) as sunk
  903. from classes c
  904. group by country;
  905.  
  906. -- най-добре - с CASE (не е нужно да се учи за контролното)
  907.  
  908. -- 9. Намерете за всеки клас с поне 3 кораба броя на корабите от този клас,
  909. -- които са с резултат ok.
  910. select class, count(distinct ship) -- повторения има, ако даден кораб е бил ok в няколко битки
  911. from ships
  912. left join outcomes on name = ship and result = 'ok'
  913. group by class
  914. having count(distinct name) >= 3; -- повторения има, ако даден кораб е бил ok в няколко битки
  915.  
  916. use movies;
  917. -- За всяка филмова звезда да се изведе името, рождената дата и с кое
  918. -- студио е записвала най-много филми. (Ако има две студиа с еднакъв
  919. -- брой филми, да се изведе кое да е от тях)
  920. select name, birthdate, (select top 1 studioname
  921.                          from starsin
  922.                          join movie on movietitle = title and movieyear = year
  923.                          where starname = name
  924.                          group by studioname
  925.                          order by count(*) desc) studioName
  926. from moviestar;
  927.  
  928. use pc;
  929. -- Намерете за всички производители на поне 2 лазерни
  930. -- принтера броя на произвежданите от тях PC-та (конкретни конфигурации), евентуално 0.
  931. select maker, count(pc.code)
  932. from product p
  933. left join pc on p.model = pc.model
  934. where maker in (select maker
  935.                 from product
  936.                 join printer on product.model = printer.model
  937.                 where printer.type = 'Laser' -- в Product също има колона type
  938.                 group by maker
  939.                 having count(*) >= 2)
  940. group by maker;
  941. -- или в having:
  942. select maker, count(pc.code)
  943. from product p
  944. left join pc on p.model = pc.model
  945. group by maker
  946. having maker in (select maker
  947.                 from product
  948.                 join printer on product.model = printer.model
  949.                 where printer.type = 'Laser' -- в Product също има колона type
  950.                 group by maker
  951.                 having count(*) >= 2);
  952. -- OR
  953. select maker, (select count(*)
  954.             from product p1
  955.             join pc on p1.model = pc.model
  956.                 and p1.maker = p.maker)
  957. from product p
  958. join printer on p.model = printer.model
  959. where printer.type = 'Laser'
  960. group by maker
  961. having count(*) >= 2;
  962.  
  963. -- да се изведат всички производители,
  964. -- за които средната цена на произведените компютри
  965. -- е по-ниска от средната цена на техните лаптопи:
  966. select maker
  967. from product p
  968. join pc on p.model = pc.model
  969. group by maker
  970. having avg(price) < (select avg(price)
  971.                      from product
  972.                      join laptop on product.model = laptop.model
  973.                      where maker = p.maker); -- корелативна подзаявка в having
  974.  
  975. -- Един модел компютри може да се предлага в няколко конфигурации
  976. -- с евентуално различна цена. Да се изведат тези модели компютри,
  977. -- чиято средна цена (на различните му конфигурации) е по-ниска
  978. -- от най-евтиния лаптоп, произвеждан от същия производител.
  979. select pc.model
  980. from pc
  981. join product p on pc.model = p.model
  982. group by pc.model, p.maker -- трябва да групираме и по maker, понеже
  983.         -- го подаваме на корелативна подзаявка в having
  984. having avg(price) < (select min(price)
  985.                     from laptop
  986.                     join product t
  987.                     on laptop.model = t.model
  988.                     where t.maker = p.maker);
  989. -- или:
  990. select pc.model
  991. from pc join product p on pc.model=p.model
  992. group by pc.model
  993. having avg(price) < (select min(price)
  994.         from laptop
  995.         join product t
  996.         on laptop.model = t.model
  997.         where t.maker = min(p.maker)); -- този min не се изпълнява в where,
  998.         -- а в having и подзаявката получава стойността, върната от min
  999.  
  1000.  
  1001.  
  1002.  
  1003. -----------
Add Comment
Please, Sign In to add comment