loading..
Русский    English
21:38
листать

Упражнение 46 (подсказки и решения)

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

Консоль
Выполнить
  1. -- Корабли, участвующие в битве при Гвадалканале и которые есть в Ships
  2. -- Обратите внимание на использование коррелирующего подзапроса в
  3. -- предложении WHERE, который решает проблему устранения дубликатов при
  4. -- декартовом произведения
  5. SELECT a.ship, displacement, numGuns
  6. FROM (SELECT ship
  7. FROM Outcomes
  8. WHERE battle = 'Guadalcanal'
  9. ) AS a, Classes
  10. WHERE class IN (SELECT class
  11. FROM Ships
  12. WHERE name = a.ship
  13. )
  14. UNION
  15. -- Аналогичный по логике запрос, который выбирает те головные корабли из
  16. -- Outcomes, которые сражались при Гвадалканале.
  17. SELECT a.ship, displacement, numGuns
  18. FROM (SELECT ship
  19. FROM Outcomes
  20. WHERE battle = 'Guadalcanal'
  21. ) AS a, Classes
  22. WHERE class IN (SELECT ship
  23. FROM Outcomes
  24. WHERE ship = a.ship
  25. )
  26. UNION
  27. --По сути, это решение 3.1.1
  28. SELECT a.ship, displacement, numGuns
  29. FROM (SELECT ship
  30. FROM Outcomes
  31. WHERE battle = 'Guadalcanal'
  32. ) AS a LEFT JOIN
  33. Classes ON a.ship = class;

В результате получим лишние строки, характерным примером которых являются такие:

ship displacement numGuns
California 32000 12
California NULL NULL

Можно еще утяжелить этот запрос (и сделать его менее эффективным), добавив код для исключения ошибочной строки. Критерием здесь может служить присутствие NULL-значения, например, в столбце displacement, если есть другая строка с тем же именем корабля. Однако мы советуем обойтись без этого и решить задачу иначе. Тем более, что это возможно, в чем легко убедиться, зайдя на форум сайта, посвященный этой задаче.

В заключение приведем почти правильное решение:

Консоль
Выполнить
  1. SELECT name, displacement, numGuns
  2. FROM Classes, Ships
  3. WHERE Classes.class = Ships.class AND
  4. name IN (SELECT Ship
  5. FROM Outcomes
  6. WHERE battle = 'Guadalcanal'
  7. )
  8. UNION
  9. SELECT class, displacement, numGuns
  10. FROM Classes
  11. WHERE class IN(SELECT ship
  12. FROM Outcomes
  13. WHERE battle = 'Guadalcanal'
  14. );

Первый запрос из объединения в этом решении находит информацию о кораблях, которые есть в таблице Ships и которые принимали участие в сражение при Гвадалканале.

Второй запрос находит нужные нам головные корабли в Outcomes. Возможные дубликаты (когда головной корабль имеется также и в таблице Ships) исключаются использованием предложения UNION.

Так что же здесь неверно? Если до сих пор непонятно, вернитесь к обсуждению задачи в пункте 3.1.

Вернуться к обсуждению упражнения 46

Решить задачу на SQL-EX.RU

Bookmark and Share
Тэги:
ALL AND AUTO_INCREMENT AVG battles CASE CAST CHAR CHARINDEX CHECK classes COALESCE CONSTRAINT Convert COUNT CROSS APPLY CTE DATEADD DATEDIFF DATENAME DATEPART DATETIME DDL DEFAULT DELETE DISTINCT DML EXCEPT EXISTS EXTRACT FOREIGN KEY FROM FULL JOIN GROUP BY Guadalcanal HAVING IDENTITY IN INNER JOIN insert INTERSECT IS NOT NULL IS NULL ISNULL laptop LEFT LEFT OUTER JOIN LEN maker MAX Больше тэгов
Учебник обновлялся
сегодня
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.
Rambler's Top100