loading..
Русский    English
23:41
листать

Упражнение 54 стр. 1

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

Решение 3.10.1

Консоль
Выполнить
  1. SELECT ROUND(SUM(ng)/SUM(cnt), 2) res
  2. FROM (SELECT SUM(numGuns) ng, COUNT(*) cnt
  3. FROM Classes c,Ships s
  4. WHERE c.class = s.class AND
  5. c.type = 'bb'
  6. UNION ALL
  7. SELECT SUM(numGuns) ng, COUNT(*) cnt
  8. FROM Classes c, Outcomes o
  9. WHERE c.class = o.ship AND
  10. c.type = 'BB'AND
  11. NOT EXISTS (SELECT name FROM Ships s
  12. WHERE s.name = o.ship)
  13. ) x;

В этом решении сделана попытка вручную посчитать среднее как сумму значений, деленную на их количество. Однако специфика арифметических операций в  Cистема управления реляционными базами данных (СУБД), разработанная корпорацией Microsoft. Язык структурированных запросов) — универсальный компьютерный язык, применяемый для создания, модификации и управления данными в реляционных базах данных. SQL Server состоит в том, что результат всегда приводится к типу аргумента. Поскольку число орудий — целое число (тип INTEGER для столбца numGuns), то дробная часть числа, полученного при делении, будет попросту отбрасываться, что заведомо даст неправильный результат.

Внимание:

Использование функции AVG для вычисления среднего не меняет ситуацию, так как приведение типа проводится по тем же правилам. Это легко проверить, если выполнить запрос

Консоль
Выполнить
  1. SELECT AVG(3/2);
который даст 1, а не 2, если бы выполнялось округление.

Если вы будете выполнять аналогичные запросы на сайте, поставьте флажок «Без проверки» на странице с упражнениями, чтобы система не выполняла бесполезного сравнения результата с эталонным решением соответствующего упражнения.

Для получения «точного» результата деления целых чисел нужно привести операнд (хотя бы один) к вещественному типу. Это можно сделать с помощью функции приведения типа CAST или простым умножением на вещественную единицу, как мы и поступим:

  1. SELECT SUM(numGuns*1.0) ng;

Теперь поговорим об округлении, которое использует функцию  T-SQL (Transact-SQL) — процедурное расширение языка SQL, используемое для программирования на стороне сервера в Microsoft SQL Server и Sybase ASE.T-SQL ROUND. Опять обратимся к простому примеру (округление до двух цифр после десятичной точки):

Консоль
Выполнить
  1. SELECT ROUND(AVG(5.0/3),2);
который даст нам 1.670000 в качестве результата. То есть округление выполнено правильно, но сохранены незначащие нули, количество которых соответствует числу значащих цифр, используемых по умолчанию для представления вещественного числа. Это число, естественно, зависит от реализации, поэтому в данном случае мы говорим лишь об SQL Server. Здесь уместно заметить, что при сравнении результатов с «правильным» решением значения 1.67 и 1.670000 будут считаться разными. Поэтому нужно позаботиться еще и об удалении этих нулей. Отложим этот вопрос до анализа следующего решения, так как там эта проблема, как и проблема округления, решена верно. Там же мы рассмотрим и логическую ошибку, которую содержит решение 3.10.1.


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