Рейтинг  

Яндекс.Метрика
Яндекс цитирования
 

   

Статистика  

Пользователи
7
Материалы
592
Кол-во просмотров материалов
2825074
   

База данных "Корабли".

Рассматривается БД кораблей, участвовавших во второй мировой войне. Имеются следующие отношения:

Название таблицы Поля таблицы
Classes (class, type, country, numGuns, bore, displacement)
Ships (name, class, launched)
Battles (name, date)
Outcomes (ship, battle, result)

Корабли в «классах» построены по одному и тому же проекту, и классу присваивается либо имя первого корабля, построенного по данному проекту, либо названию класса дается имя проекта, которое не совпадает ни с одним из кораблей в БД. Корабль, давший название классу, называется головным.

Отношение Classes содержит
имя класса,
тип (bb для боевого (линейного) корабля или bc для боевого крейсера),
страну, в которой построен корабль,
число главных орудий,
калибр орудий (диаметр ствола орудия в дюймах) и
водоизмещение (вес в тоннах).

В отношении Ships записаны
название корабля,
имя его класса и
год спуска на воду.

В отношение Battles включены
название и
дата битвы, в которой участвовали корабли
,

а в отношении Outcomesрезультат участия данного корабля в битве (потоплен - sunk, поврежден - damaged или невредим - OK).

Замечания.
1) В отношение Outcomes могут входить корабли, отсутствующие в отношении Ships.
2) Потопленный корабль в последующих битвах участия не принимает.

Задание 14:

Найдите класс, имя и страну для кораблей из таблицы Ships, имеющих не менее 10 орудий.

SQL-запрос 14:


SELECT DISTINCT S.class, S.name, C.country FROM Ships AS S,
(SELECT class, country, numGuns
 FROM Classes WHERE numGuns>=10) AS C # 2-ая таблица, сделанная 'на лету'
WHERE S.class=C.class



Задание 31:

Для классов кораблей, калибр орудий которых не менее 16 дюймов, укажите класс и страну.

SQL-запрос 31:


SELECT class, country FROM Classes
WHERE bore >= 16



Задание 33:

Укажите корабли, потопленные в сражениях в Северной Атлантике (North Atlantic).
Вывод: ship.

SQL-запрос 33:


SELECT DISTINCT ship FROM outcomes
WHERE battle='North Atlantic' AND result='sunk'



Задание 34:

По Вашингтонскому международному договору от начала 1922 г. запрещалось строить линейные корабли водоизмещением более 35 тыс.тонн. Укажите корабли, нарушившие этот договор (учитывать только корабли c известным годом спуска на воду).
Вывести названия кораблей.

SQL-запрос 34:


SELECT DISTINCT name FROM classes,
    (SELECT class, name, launched FROM ships
    WHERE launched >= 1922) AS T
WHERE classes.class = T.class AND displacement > 35000



Задание 36:

Перечислите названия головных кораблей, имеющихся в базе данных (учесть корабли в Outcomes).

SQL-запрос 36:


SELECT name FROM classes, ships
WHERE classes.class = name
UNION
SELECT ship FROM classes, outcomes
WHERE classes.class = ship



Задание 37:

Найдите классы, в которые входит только один корабль из базы данных (учесть также корабли в Outcomes).

SQL-запрос 37:


SELECT CL.class FROM classes CL
LEFT JOIN (
   SELECT class, name
   FROM ships
   UNION
   SELECT ship, ship
   FROM outcomes
) AS s
ON s.class = CL.class
GROUP BY CL.class
HAVING COUNT(s.name) = 1



Задание 38:

Найдите страны, имевшие когда-либо классы обычных боевых кораблей ('bb') и имевшие когда-либо классы крейсеров ('bc').

SQL-запрос 38:


WITH T AS (
    SELECT DISTINCT country, type
    FROM classes
    WHERE type = 'bb' OR type = 'bc'
)
SELECT country FROM T
GROUP BY country
HAVING COUNT(country) = 2



Задание 39:

Найдите корабли, `сохранившиеся для будущих сражений`; т.е. выведенные из строя в одной битве (damaged), они участвовали в другой, произошедшей позже.

SQL-запрос 39:


SELECT DISTINCT ship FROM outcomes o, battles b
WHERE result='damaged'
AND
EXISTS (
    SELECT DISTINCT ship, date FROM outcomes, battles
    WHERE o.ship = outcomes.ship
    AND b.date < battles.date
    AND outcomes.result = 'OK'
)


WITH T AS (
    SELECT DISTINCT ship, result, date FROM outcomes, battles
    WHERE battle = name
)
SELECT DISTINCT T1.ship FROM T T1, T T2
WHERE T1.ship = T2.ship
AND T1.date < T2.date
AND T2.result = 'OK'


WITH T AS (
    SELECT DISTINCT ship, result, date FROM outcomes, battles
    WHERE battle = name
)
SELECT T1.ship FROM T T1, T T2
WHERE T1.ship = T2.ship
AND T1.date < T2.date
AND T1.result = 'damaged'
AND T2.result != 'damaged'


WITH T AS (
    SELECT DISTINCT ship, result, date FROM outcomes, battles
    WHERE battle = name
)
SELECT DISTINCT T2.ship FROM T T2
WHERE T2.ship IN (
    SELECT ship FROM T T1
    WHERE T1.date < T2.date AND T1.result = 'damaged'
)


WITH BT AS (
    SELECT O.ship, B.name, B.date, O.result
    FROM outcomes O
    LEFT JOIN battles B ON O.battle = B.name
)
SELECT DISTINCT A.ship FROM BT A
WHERE A.ship IN (
    SELECT ship FROM BT B
    WHERE B.date < A.date AND B.result = 'damaged'
)


Задание 42:

Найдите названия кораблей, потопленных в сражениях, и название сражения, в котором они были потоплены.

SQL-запрос 42:


SELECT ship, battle FROM outcomes
WHERE result='sunk'


Задание 43:

Укажите сражения, которые произошли в годы, не совпадающие ни с одним из годов спуска кораблей на воду.

SQL-запрос 43:


SELECT DISTINCT name FROM battles
WHERE NOT EXISTS (
    SELECT DISTINCT launched FROM ships
    WHERE YEAR(date) = launched
)


Задание 44:

Найдите названия всех кораблей в базе данных, начинающихся с буквы R.

SQL-запрос 44:


SELECT DISTINCT name FROM ships
WHERE name LIKE 'R%'
UNION
SELECT DISTINCT ship FROM outcomes
WHERE ship LIKE 'R%'


Задание 45:

Найдите названия всех кораблей в базе данных, состоящие из трех и более слов (например, King George V). Считать, что слова в названиях разделяются единичными пробелами, и нет концевых пробелов.

SQL-запрос 45:


SELECT name FROM ships
WHERE name LIKE '% % %'
UNION
SELECT ship FROM outcomes
WHERE ship LIKE '% % %'


Задание 46:

Для каждого корабля, участвовавшего в сражении при Гвадалканале (Guadalcanal), вывести название, водоизмещение и число орудий.

SQL-запрос 46:


SELECT DISTINCT S.name, displacement, numGuns
FROM classes C, ships S, outcomes O
WHERE C.class = S.class AND S.name = O.ship AND O.battle = 'Guadalcanal'


SELECT DISTINCT S.name, displacement, numGuns FROM classes C, ships S, outcomes O
WHERE C.class = S.class AND S.name = O.ship AND
    EXISTS (
        SELECT ship FROM outcomes, battles
        WHERE name = 'Guadalcanal'
    )


SELECT DISTINCT S.name, displacement, numGuns
FROM classes C, ships S, outcomes O
WHERE C.class = S.class AND S.name = O.ship
  AND O.battle = 'Guadalcanal'
UNION
SELECT DISTINCT O.ship, displacement, numGuns
FROM classes C, outcomes O
WHERE C.class = O.ship
  AND O.battle = 'Guadalcanal'


Задание 48:

Найдите классы кораблей, в которых хотя бы один корабль был потоплен в сражении.

SQL-запрос 48:


SELECT C.class FROM Classes C
LEFT JOIN Ships S ON S.class = C.class
WHERE C.class IN (
    SELECT ship FROM Outcomes
    WHERE result = 'sunk'
)
OR S.name IN (
    SELECT ship FROM Outcomes
    WHERE result = 'sunk'
)
GROUP BY C.class



WITH T AS ( 
    SELECT ship FROM Outcomes
    WHERE result = 'sunk'
)
SELECT C.class FROM Classes C
LEFT JOIN Ships S ON S.class = C.class
WHERE C.class IN (SELECT * FROM T)
OR S.name IN (SELECT * FROM T)
GROUP BY C.class


Задание 49:

Найдите названия кораблей с орудиями калибра 16 дюймов (учесть корабли из таблицы Outcomes).

SQL-запрос 49:


SELECT DISTINCT name FROM Classes C, Ships S
WHERE bore = 16
AND C.class = S.class
UNION
SELECT DISTINCT ship FROM Classes C, outcomes O
WHERE bore = 16
AND O.ship = C.class


Задание 52:

Определить названия всех кораблей из таблицы Ships, которые могут быть линейным японским кораблем, имеющим число главных орудий не менее девяти, калибр орудий менее 19 дюймов и водоизмещение не более 65 тыс.тонн.

SQL-запрос 52:


SELECT S.name FROM ships S, classes C
WHERE S.class = C.class
  AND (numGuns >= 9 OR numGuns is NULL)
  AND (bore < 19 OR bore is NULL)
  AND (displacement <= 65000 OR displacement is NULL)
  AND UPPER(country) = 'JAPAN'
  AND type = 'bb'


Задание 53:

Определите среднее число орудий для классов линейных кораблей. Получить результат с точностью до 2-х десятичных знаков.

SQL-запрос 53:


SELECT CAST(AVG(CAST(numGuns AS REAL)) AS NUMERIC(4,2))
FROM classes
WHERE type='bb'


Задание 54:

С точностью до 2-х десятичных знаков определите среднее число орудий всех линейных кораблей (учесть корабли из таблицы Outcomes).

SQL-запрос 54:


WITH T AS (
    SELECT name, numGuns, type FROM classes C, ships S
    WHERE C.class = S.class
    UNION
    SELECT ship, numGuns, type FROM classes C, outcomes O
    WHERE C.class = O.ship  
)
SELECT CAST(AVG(CAST(numGuns AS REAL)) AS NUMERIC(4,2))
FROM T
WHERE type='bb'


Задание 55:

Для каждого класса определите год, когда был спущен на воду первый корабль этого класса. Если год спуска на воду головного корабля неизвестен, определите минимальный год спуска на воду кораблей этого класса.
Вывести: класс, год.

SQL-запрос 55:


WITH T AS (
    SELECT C.class, name, launched FROM classes C, ships S
    WHERE C.class = S.class
    UNION
    SELECT class, class, NULL FROM classes C
)
SELECT class, MIN(launched) FROM T
GROUP BY class


Задание 56:

Для каждого класса определите число кораблей этого класса, потопленных в сражениях.
Вывести: класс и число потопленных кораблей.

SQL-запрос 56:


WITH T AS (
    SELECT C.class, name, result FROM classes C, ships S, outcomes O
    WHERE C.class = S.class AND S.name = O.ship
    UNION
    SELECT class, ship, result FROM classes, outcomes
    WHERE class = ship
)
SELECT T.class,
       (CASE WHEN COUNT(result) > 0
       THEN COUNT(result)
       ELSE 0 END)
FROM T
GROUP BY T.class






Задание 57:

SQL-запрос 57:





Задание 70:

Укажите сражения, в которых участвовало по меньшей мере три корабля одной и той же страны.

SQL-запрос 70:


WITH T AS ( 
    SELECT country, name FROM classes C, ships S
    WHERE C.class = S.class
)
SELECT battle FROM outcomes
INNER JOIN T
ON name = ship
GROUP BY battle
HAVING COUNT(battle) >= 3



SELECT DISTINCT O.battle FROM outcomes O
LEFT JOIN ships S ON S.name = O.ship
LEFT JOIN classes C ON O.ship = C.class OR S.class = C.class
WHERE C.country IS NOT NULL
GROUP BY C.country, O.battle
HAVING COUNT(O.ship) >= 3





Получить таблицу страна и количество строк с этими странами:


WITH T AS (
SELECT country, C.class, name FROM classes C, ships S
WHERE C.class = S.class
)
SELECT country, COUNT(country) AS CNT FROM T
GROUP BY country


WITH T AS (
    SELECT country, COUNT(country) AS CNT FROM (
        SELECT country, name FROM classes C, ships S
        WHERE C.class = S.class
    ) AS A
    GROUP BY country
)
SELECT * FROM T


Получить по конкретной стране количество с этой страной:


WITH T AS (
SELECT country, C.class, name FROM classes C, ships S
WHERE C.class = S.class
)
SELECT country, COUNT(country) AS CNT FROM T
WHERE UPPER(country) = 'JAPAN'
GROUP BY country


   
   

Login Form