Упражнение 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
);
[[ column ]] |
---|
[[ value ]] |
Поскольку достаточно лишь двух ПК с одинаковыми жесткими дисками, можно использовать самосоединение таблицы PC по аналогичным условиям:
SELECT DISTINCT pc1.hd
FROM PC pc1, PC pc2
WHERE pc1.hd = pc2.hd
AND pc1.code <> pc2.code;
[[ column ]] |
---|
[[ value ]] |
Однако наиболее оптимальным будет решение с группировкой и условиями отбора в предложении HAVING:
SELECT PC.hd
FROM PC
GROUP BY hd
HAVING COUNT(hd) > 1;
[[ column ]] |
---|
[[ value ]] |
Для полноты картины приведем еще одно решение, которое использует подзапрос с группировкой и которое по эффективности также уступает вышеприведенному.
SELECT DISTINCT hd
FROM PC
WHERE (SELECT COUNT(hd)
FROM PC pc2
WHERE pc2.hd = pc.hd
) > 1;
[[ column ]] |
---|
[[ value ]] |
Причина низкой эффективности рассмотренных решений с подзапросами заключается в том, что все они используют коррелирующий подзапрос, то есть подзапрос, который будет выполняться для каждой строки основного запроса. Запрос с соединением имеет самую низкую производительность. Это вполне понятно, так как операции соединения весьма затратные, несмотря на достаточно эффективные алгоритмы их реализации [5].