[sql] SQL에서 “0으로 나누기”오류를 피하는 방법은 무엇입니까?

이 오류 메시지가 있습니다 :

메시지 8134, 수준 16, 상태 1, 줄 1 오류 0으로 나눕니다.

이 오류 메시지가 다시 표시되지 않도록 SQL 코드를 작성하는 가장 좋은 방법은 무엇입니까?

다음 중 하나를 수행 할 수 있습니다.

  • 제수가 제로가 아닌 where 절을 추가하십시오.

또는

  • case statement를 추가하여 0에 대한 특별한 처리가 가능합니다.

NULLIF절 을 사용하는 가장 좋은 방법 입니까?

더 좋은 방법이 있습니까, 아니면 어떻게 시행 할 수 있습니까?



답변

“0으로 나누기”오류를 피하기 위해 다음과 같이 프로그래밍했습니다.

Select Case when divisor=0 then null
Else dividend / divisor
End ,,,

그러나 여기에 훨씬 좋은 방법이 있습니다.

Select dividend / NULLIF(divisor, 0) ...

이제 유일한 문제는 “/”키를 사용하면 NullIf 비트를 기억하는 것입니다.


답변

0을 반환하려는 경우 0 수정이 발생할 경우 다음을 사용할 수 있습니다.

SELECT COALESCE(dividend / NULLIF(divisor,0), 0) FROM sometable

제수가 0 인 모든 제수에 대해 결과 집합에서 0을 얻습니다.


답변

이것은 데이터에서 발생하는 0으로 나누기를 해결하려고 할 때 내 상황에 가장 적합한 것으로 보였습니다.

다양한 학교 클럽의 남녀 비율을 계산하려고하는데 다음 쿼리가 실패하고 반지가없는 클럽의 비율을 계산하려고 할 때 0으로 나누기 오류가 발생한다고 가정합니다. :

SELECT club_id, males, females, males/females AS ratio
  FROM school_clubs;

이 기능 NULLIF을 사용하면 0으로 나누지 않아도됩니다. NULLIF두 표현식을 비교하고 같으면 null을 반환하고 그렇지 않으면 첫 표현식을 반환합니다.

다음과 같이 쿼리를 다시 작성하십시오.

SELECT club_id, males, females, males/NULLIF(females, 0) AS ratio
  FROM school_clubs;

주어진 수로 나눈 값 NULLNULL오류가 발생하지 않습니다.


답변

쿼리 시작시이 작업을 수행 할 수도 있습니다.

SET ARITHABORT OFF
SET ANSI_WARNINGS OFF

따라서 이와 같은 100/0것이 있으면 NULL을 반환합니다. 간단한 쿼리에 대해서만이 작업을 수행 했으므로 더 길고 복잡한 쿼리에 어떤 영향을 줄지 모르겠습니다.


답변

오류로 인해 쿼리가 중단되는 것을 최소한 중지하고 NULL0으로 나눈 값을 반환 할 수 있습니다.

SELECT a / NULLIF(b, 0) FROM t 

그러나 많은 찬사를 얻은 다른 답변에 표시된 것처럼 절대로 이것을 0으로 변환하지 않습니다 coalesce. 이것은 수학적 의미에서 완전히 잘못되었으며 응용 프로그램에서 잘못되고 잘못된 결과를 반환 할 수 있으므로 위험합니다.


답변

편집 : 최근에 많은 downvotes가 생겼습니다 … 그래서이 답변이 가장 최근의 편집을 받기 전에 작성되었다는 메모를 추가한다고 생각했습니다 .null을 반환하는 것이 옵션으로 강조 표시되었습니다. 매우 수용 가능한 것 같습니다. 내 대답 중 일부는 Edwardo와 같은 문제에 대한 답변에서 0을 반환하는 것을 옹호하는 것처럼 보였습니다. 이것은 내가 반대하는 경우입니다.

답변 : 여기에 근본적인 문제가 있다고 생각합니다 .0으로 나누는 것은 합법적이지 않습니다. 뭔가 근본적으로 잘못되었음을 나타냅니다. 0으로 나누면 수학적으로 이해가되지 않는 것을 시도하고 있으므로 얻을 수있는 숫자 답변이 유효하지 않습니다. (이 경우 널을 사용하면 나중에 수학적 계산에 사용될 값이 아니므로 합리적입니다).

따라서 Edwardo는 “사용자가 0을 입력하면 어떻게됩니까?”라는 의견을 묻습니다. 사용자가 금액에 0을 넣고 그 때 0을 반환하려면 비즈니스 규칙 수준에서 코드를 입력하여 해당 값을 포착하고 0을 반환해야합니다 .0으로 나누는 특별한 경우는 없습니다 = 0.

그것은 미묘한 차이이지만, 다음에 누군가가 함수를 호출하고 올바른 일을 할 것으로 기대하기 때문에 수학적으로 정확하지 않지만 펑키 한 일을하지만 특정 에지 케이스를 처리하기 때문에 중요합니다. 나중에 누군가를 물릴 수있는 좋은 기회입니다. 당신은 실제로 0으로 나누지 않습니다 … 당신은 단지 나쁜 질문에 대한 잘못된 대답을 반환합니다.

내가 무언가를 코딩하고 있다고 상상해보십시오. 나는 방사선 측정 스케일링 값으로 읽어야하지만 이상한 가장자리 케이스에서는 예상하지 못했지만 0을 읽습니다. 그런 다음 내 값을 함수에 버립니다 … 당신은 0을 반환합니다! 만세, 방사선 없음! 그것이 실제로 있다는 것을 제외하고는 내가 나쁜 가치를 전달했다는 것입니다 …하지만 나는 모른다. 뭔가 잘못되었다는 표시이기 때문에 나누기가 오류를 던지기를 원합니다.


답변

SELECT Dividend / ISNULL(NULLIF(Divisor,0), 1) AS Result from table

nullif ()를 사용하여 0을 포착 한 다음 isnull ()을 사용하여 결과로 생성 된 널을 0으로 나누면 0으로 나누기 오류를 피할 수 있습니다.