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

Неверное решение 1.11.1 этой задачи легко поправить, если различать ПК не по номеру модели, а, как и положено, по первичному ключу — столбцу code:

SELECT DISTINCT t.hd
FROM PC t
WHERE EXISTS (SELECT *
            FROM PC
            WHERE pc.hd = t.hd 
            AND pc.code <> t.code
            );
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Поскольку достаточно лишь двух ПК с одинаковыми жесткими дисками, можно использовать самосоединение таблицы PC по аналогичным условиям:

SELECT DISTINCT pc1.hd
FROM PC pc1, PC pc2
WHERE pc1.hd = pc2.hd 
    AND pc1.code <> pc2.code;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Однако наиболее оптимальным будет решение с группировкой и условиями отбора в предложении HAVING:

SELECT PC.hd 
FROM PC
GROUP BY hd
HAVING COUNT(hd) > 1;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

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

SELECT DISTINCT hd
FROM PC
WHERE (SELECT COUNT(hd)
       FROM PC pc2
       WHERE pc2.hd = pc.hd
       ) > 1;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Причина низкой эффективности рассмотренных решений с подзапросами заключается в том, что все они используют коррелирующий подзапрос, то есть подзапрос, который будет выполняться для каждой строки основного запроса. Запрос с соединением имеет самую низкую производительность. Это вполне понятно, так как операции соединения весьма затратные, несмотря на достаточно эффективные алгоритмы их реализации [5].

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

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