Упражнение 5

Найдите номер модели, скорость и размер жесткого диска ПК, имеющих 12х или 24х CD и цену менее 600 долларов.

При решении этой задачи обычно совершают две типичные ошибки.

Первая ошибка связана с интуитивным предположением, что скорость CD-устройства является целочисленным значением. В результате запрос

SELECT PC.model, PC.speed, PC.hd
FROM PC
WHERE PC.cd IN (12, 24) 
    AND price < 600;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

выдаст ошибку приведения несовместимых типов данных:

Conversion failed when converting the varchar value '12x' to data type int.

(«Ошибка при преобразовании значения ‘12x’ типа varchar к типу данных int»)

Внимательное чтение схемы данных скажет, что столбец cd имеет тип varchar. Поэтому, чтобы получить правильное решение достаточно переписать запрос в виде:

SELECT PC.model, PC.speed, PC.hd
FROM PC
WHERE PC.cd IN ('12x', '24x') 
    AND price < 600;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Вторая ошибка логическая и заключается в неправомерном использовании предиката BETWEEN. Вот это решение:

SELECT model, speed, hd
FROM PC
WHERE price < 600 
    AND cd BETWEEN '12x' AND '24x';
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Даже если предположить, что между моделями 12х и 24х-скоростных CD-приводов нет других моделей (скажем, 20х), решение не будет верным в силу правила сравнения строковых значений. Это правило гласит, что строки сравниваются посимвольно до первого отличающегося символа. Далее вывод о сравнении строк целиком делается на основании результата сравнения отличающихся символов. Например, справедливо ‘abcz’ < ‘abd’, так как первый отличающийся символ в первой строке (‘c’) меньше соответствующего символа второй строки (’d’). Если одна строка является префиксом второй (например, ‘упражнения’ и ‘упражнениями’), то истинным будет сравнение ‘упражнения’ < ‘упражнениями’.

Здесь уместно заметить, что сравнение (и соответственно порядок сортировки) зависит от параметра COLLATION [3]. Повсюду, если не оговорено противное, мы будем предполагать, что все текстовые поля имеют одинаковую установку этого параметра, обеспечивающего сравнение, независящее от регистра символов.

Предикат BETWEEN эквивалентен одновременному выполнению двух простых операторов сравнения:

cd >= ‘12x’ AND cd <= ‘24x’

Исходя из вышесказанного, этому предикату будут удовлетворять, помимо требуемых задачей, например, следующие значения:

‘130x’, 145’, ‘150000000000y’ и т. д.

Еще одним вариантом решения этой несложной задачи будет использование двух предикатов простого сравнения:

SELECT PC.model, PC.speed, PC.hd
FROM PC
WHERE (PC.cd = '12x' 
    OR PC.cd = '24x') 
    AND price < 600;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Если вы не нашли здесь объяснения своей ошибки, загляните сюда.

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