2009-05-12 3 views
5

에 의해 제거된다 카운트 독특하고 Null 값은 (내 실제 쿼리에서 간체) 나는 아래의 쿼리와 SQL 서버 2005을 사용하고 집계

select a,count(distinct b),sum(a) from 
(select 1 a,1 b union all 
select 2,2 union all 
select 2,null union all 
select 3,3 union all 
select 3,null union all 
select 3,null) a 
group by a 

이없는 별개의 수를 할 수있는 방법이 있습니까

"경고 : Null 값이 집계 또는 다른 SET 연산에 의해 제거됩니다."점점 두 쿼리 수를 별개의 하나에 분리

  • 떨어져

    1. 켜기 ANSI_WARNINGS와 합 절은 널 (null)을 제거하기 위해 어디 하나 : 여기

      내가 생각할 수있는 대안

      select t1.a, t1.countdistinctb, t2.suma from 
      (
          select a,count(distinct b) countdistinctb from 
          (
           select 1 a,1 b union all 
           select 2,2 union all 
           select 2,null union all 
           select 3,3 union all 
           select 3,null union all 
           select 3,null 
          ) a 
          where a.b is not null 
          group by a 
      ) t1 
      left join 
      (
          select a,sum(a) suma from 
          (
           select 1 a,1 b union all 
           select 2,2 union all 
           select 2,null union all 
           select 3,3 union all 
           select 3,null union all 
           select 3,null 
          ) a 
          group by a 
      ) t2 on t1.a=t2.a 
      
    2. 는 클라이언트의 경고를 무시

    ,

    더 좋은 방법이 있나요? 아마 2 번 경로를 따라갈 것이지만 코드 중복을 싫어할 것입니다. 어느 곳

  • +0

    나는 당신의 이전 코드는 잘 생각 데이터베이스해야 어떤 프로그래머가 DISTINCT가 어쨌든 계산 널 (null)을 포함해야한다고 생각하는 경향 될 수 있기 때문에, 경고를 올릴 이유 놀라움으로 문제가 당신에게. 나는 경고 경고가 ANSI SQL을 준수한다고 생각한다. –

    +0

    당신의 설명이 이치에 맞습니다. 그래도 나는 그들을 피할 수 있다면 경고를 좋아하지 않는다. –

    답변

    5
    select a,count(distinct isnull(b,-1))-sum(distinct case when b is null then 1 else 0 end),sum(a) from 
        (select 1 a,1 b union all 
        select 2,2 union all 
        select 2,null union all 
        select 3,3 union all 
        select 3,null union all 
        select 3,null) a 
        group by a 
    

    감사 역을 할 수있는 나는이 작업을 수행 할 수있는 방법을했다. null을 포함하여 값을 구별 할 수 있으며, 별개의 sum을 사용하는 경우 널 (NULL)로 인해 계수를 제거 할 수 있습니다.

    2

    당신은 가능성이 반환 널 사용이

    CASE WHEN Column IS NULL THEN -1 ELSE Column END AS Column 
    
    쿼리의 기간 동안 -1에 대한 모든 null 값을 서브하고 그들이 계산/당신에게 다음과 같은 집계됩니다

    그냥 ... 당신의 잘 포장 쿼리에 에오로

    SELECT 
        CASE WHEN t1.a = -1 THEN NULL ELSE t1.a END as a 
        , t1.countdistinctb 
        , t2.suma 
    
    +0

    두 개의 쿼리로 분할 및 결합하는 것을 피하고자했습니다. 귀하의 아이디어 덕분에 나는 그것을 해결했지만, 나는 대답을 게시 할 것입니다. –

    +0

    이 아이디어가 전혀 마음에 들지 않습니다. 데이터가 늦게 도착하면 어떨까요? 또는 '알 수 없음'이 완벽하게 유효한 상태입니까? –

    +0

    나는 특별히 카운트에 NULL 값을 포함하고 싶지 않은 경우를 위해 설계하고 있습니다. –

    1

    코드 복제가 마음에 들지 않으면 공통 테이블 식을 사용하지 않는 이유는 무엇입니까? 예 :

    WITH x(a, b) AS 
         (
           select 1 a,1 b union all 
           select 2,2 union all 
           select 2,null union all 
           select 3,3 union all 
           select 3,null union all 
           select 3,null 
         ) 
    select t1.a, t1.countdistinctb, t2.suma from 
    (
         select a,count(distinct b) countdistinctb from 
         x a 
         where a.b is not null 
         group by a 
    ) t1 
    left join 
    (
         select a,sum(a) suma from 
         x a 
         group by a 
    ) t2 on t1.a=t2.a 
    
    +0

    그건 내가 생각하지 못한 좋은 생각이야. 그러나 내가 정말로 싫어했던 코드 중복은 그룹 바이와 조인이었는데, 이렇게 제거 할 수는 없습니다. 그래도 고마워. –

    2

    이것은 늦은 메모이지만 Google에서 반품되었으므로 언급하고 싶습니다.

    NULL을 다른 값으로 변경하는 것은 나쁜 생각 (tm)입니다.

    COUNT()는 DISTINCT가 아니라이를 수행합니다.

    는 대신, 하위 쿼리에 DISTINCT 사용하고 번호를 반환하고, 외부 쿼리에 그 집계.

    이것의 간단한 예이다

    WITH A(A) AS (SELECT NULL UNION ALL SELECT NULL UNION ALL SELECT 1) 
    SELECT COUNT(*) FROM (SELECT DISTINCT A FROM A) B; 
    

    COUNT(*) (그 레코드를 카운트하기 때문에,하지 값)가 널 (null)을 무시하지 않는, 사용하도록 허용한다.