Я пытался понять, почему я получаю «деление на ноль» (сообщение 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, но это а) не имело бы смысла имхо и б) когда при попытке воспроизвести ошибку на тестовой установке все работает нормально (см. ниже):
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.