TSQL делит на ноль, несмотря на отсутствие столбцов, содержащих 0

Я пытался понять, почему я получаю «обнаруженное деление на ноль» (Msg 8134) с моим запросом SQL, но я, должно быть, что-то упускаю. Я хотел бы знать , почему для конкретного случая ниже, я не ищу NULLIF , CASE WHEN ... или аналогичные, как я уже знаю о них (и, конечно, могу использовать их в ситуации, описанной ниже).

У меня есть оператор SQL с вычисляемым столбцом, подобный

SELECT
    TotalSize,
    FreeSpace,
    (FreeSpace / TotalSize * 100)
FROM
    tblComputer
...[ couple of joins ]...
WHERE
    SomeCondition = SomeValue

Выполнение этого оператора ошибки с вышеупомянутой ошибкой сообщений, что само по себе не является проблемой - очевидно, что TotalSize вполне может быть 0 и, следовательно, вызывать ошибку.

Я не понимаю, что у меня нет строк, в которых столбец TotalSize равен 0, когда я комментирую вычисляемый столбец, я дважды проверял, что это не так.

Тогда я подумал, что по какой-то причине вычисление столбца будет выполняться для всего набора результатов до того, как фактически будет фильтровать с условиями предложения where, но это a) не имело бы смысла imho и b ) при попытке воспроизвести ошибку с помощью тестовой конфигурации все работает нормально (см. ниже):

INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0001',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0002',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0003',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0004',0)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0005',1)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0006',0)
INSERT INTO tblComputer (ComputerName, IsServer) VALUES ('PC0007',1)

INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (1,100,21)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (2,100,10)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (3,100,55)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (4,0,10)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (5,100,23)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (6,100,18)
INSERT INTO tblHDD (ComputerID, TotalSize, FreeSpace) VALUES (7,100,11)

-- This statement does not throw an error as apparently the row for ComputerID 4 
-- is filtered out before computing the (FreeSpace / TotalSize * 100)
SELECT 
TotalSize,
FreeSpace,
(FreeSpace / TotalSize * 100)
FROM 
tblComputer
JOIN
tblHDD ON
tblComputer.ID = tblHDD.ComputerID
WHERE
IsServer = 1

Я в полном тупике и хотел бы знать, в чем причина.

Любые идеи или указатели в правильном направлении являются очень добро пожаловать, заранее спасибо

Обновление

Пока что спасибо за ваш вклад, но, к сожалению, я, похоже, не приближаюсь к корню проблемы. Мне удалось немного сократить этот оператор, и теперь я могу выполнить его без ошибок, если один JOIN будет удален (мне он понадобится для дополнительных столбцов в выводе, которые я временно удалил).

Я не понимаю, почему использование JOIN приводит к ошибке, не должно ли стандартное INNER JOIN всегда возвращать одинаковое количество строк или меньше , но никогда больше ?

Рабочий код

SELECT 
TotalSize,
FreeSpace
((FreeSpace / TotalSize) * 100)
FROM 
MyTable1
INNER JOIN 
MyTable2 ON
MyTable1.ID = MyTable2.Table1ID
WHERE 
SomeCondition

Код ошибки

SELECT 
TotalSize,
FreeSpace
((FreeSpace / TotalSize) * 100)
FROM 
MyTable1
INNER JOIN 
MyTable2 ON
MyTable1.ID = MyTable2.Table1ID
-- This JOIN causes "divide by zero encountered" error
INNER JOIN 
MyTable3 ON
MyTable2.ID = MyTable3.Table2ID
WHERE 
SomeCondition

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

Извините за беспорядочный отступ в коде, каким-то образом не удается применить правильное форматирование.

G.

10
задан Aziz Shaikh 1 October 2012 в 08:16
поделиться