programing

null 값을 고유 값으로 카운트

abcjava 2023. 6. 20. 21:18
반응형

null 값을 고유 값으로 카운트

열에 다음과 같은 다른 값을 계산해야 합니다.

Hours
1
1
2
null
null
null

결과는 3이어야 합니다.제 질문은 다음과 같습니다.

select count(distinct hour) from hours;

그러나 그것은 2.테스트도 수행했습니다.

select count(*) from hours group by hour

그러나 세 개의 행을 반환합니다.

(1) 3
(2) 2
(3) 1

null 값을 1 값으로 카운트하고 중복된 값을 카운트하지 않도록 구별하여 사용하려면 어떻게 해야 합니까?

고급 SQL을 배우고 있습니다. 모든 솔루션에 대해 다음과 같은 요구 사항을 충족해야 합니다.

쿼리를 해결하는 데 필요한 하위 쿼리 수를 최소화합니다.또한 다음 구성을 사용할 수 없습니다.

  • FROM 또는 SELECT에서 선택합니다.하위 쿼리를 가질 수 있습니다(WHERE 또는 HAVING에서 선택).
  • COUNT(COUNT. ...), SUM(COUNT. ...) 등의 집계 함수 조합.
  • 피할 수 있다면 연합.
  • 비표준 기능(예: NVL)
  • 사례.
select  count(distinct col1) + count(distinct case when col1 is null then 1 end)
from    YourTable

시간이 숫자인 경우 정수만 될 수 있는 경우:

select count(distinct coalesce(hour, 0.1)) cnt from test;

그렇지 않으면 부동 소수점이 될 수 있는 경우 NULL을 문자 문자열로 변경합니다.

예를 들어

select count(distinct coalesce(to_char(hour), 'a')) cnt from test;
select 
   count(0) 
from
  (
      select distinct hour from hours
  )

SqlFiddle

SELECT
      ( SELECT COUNT(DISTINCT hour)
        FROM hours
      )
    + CASE WHEN EXISTS
           ( SELECT *
             FROM hours
             WHERE hour IS NULL
           )
        THEN 1 
        ELSE 0
      END
   AS result
FROM dual ;

아마도요.

    select count(distinct hour||' ') from hours;

괜찮겠습니까?

select count(distinct nvl(hour,0)) from hours;

단순히 다음을 사용하여 보다 효율적인 질문을 받을 수 있다는 것을 고려할 때, 당신의 요구 사항은 꽤 이상하다고 생각합니다.NVL(),COALESCE()또는CASE하지만, 저는 올바른 결과를 얻을 수 있었습니다(그리고 그 존재 여부에 대처했습니다).NULL하위 쿼리만 사용합니다.하위 쿼리를 사용하지 않고는 이 작업을 수행할 수 없습니다.FROM아직 절

SQL 피들

쿼리 1:

SELECT nnh.not_null_hours + nh.null_hours
FROM (
  SELECT COUNT(DISTINCT t.hour) not_null_hours
  FROM example_table t
) nnh
CROSS JOIN (
  SELECT 1 null_hours
  FROM dual
  WHERE EXISTS (
    SELECT 1
    FROM example_table t
    WHERE t.hour IS NULL
  )
  UNION ALL
  SELECT 0 null_hours
  FROM dual
  WHERE NOT EXISTS (
    SELECT 1
    FROM example_table t
    WHERE t.hour IS NULL
  )
) nh

결과:

| NNH.NOT_NULL_HOURS+NH.NULL_HOURS |
------------------------------------
|                                3 |

이것은 요구 사항에 대처하기 위해 많은 노력을 들일 것입니다.훨씬 더 간단한 옵션은 사용하는 것입니다.NVL그리고 두 가지 간단한 선택 중 하나는...다음 중 하나:

  1. 사용하다TO_CHARNULL이 아닌 값을 VARCHAR2 데이터 유형으로 변환합니다.NVL개종하기 위해NULLVARCHAR2에 대한 값'NULL'또는
  2. 그냥 사용하기NVL결과 집합에 절대로 존재하지 않는 마법 번호를 사용합니다(즉, 테이블의 제약 조건 때문에).

쿼리 1:

SELECT 
  COUNT(DISTINCT NVL(TO_CHAR(hour), 'NULL')) using_to_char_null
, COUNT(DISTINCT NVL(hour, -1)) using_magic_number
FROM example_table

결과:

| USING_TO_CHAR_NULL | USING_MAGIC_NUMBER |
-------------------------------------------
|                  3 |                  3 |

Andres의 답변은 다음과 같은 기능을 전혀 사용하지 않고 요구사항을 완벽하게 충족하는 답변입니다.COUNT:

select count(distinct hour||' ') from hours;

저는 다른 목적을 위해 같은 것을 찾고 있었습니다(저는 무엇이든 사용할 수 있었습니다). 하지만 제가 이것을 보기 전까지는 그것이 정확하거나 효율적으로 보이지 않았습니다, 감사합니다, 안드레스, 그렇게 간단한 해결책이지만 강력한 해결책입니다.

지정된 기준에 가장 근접한 것은 다음과 같습니다. (SQL Fiddle)

쿼리 1:

SELECT COUNT(*)
FROM example_table t1
WHERE t1.ROWID IN (
  SELECT MAX(t2.ROWID)
  FROM example_table t2
  GROUP BY t2.hour
)

결과:

| COUNT(*) |
------------
|        3 |

확실하지 않습니다.ROWID 사항을 때 처리됩니다.NULL가치.ROWID는 Oracle 외부에 존재하지 않기 때문에 질문의 취지에 어긋날 수 있지만 적어도 나열된 기준에 부합합니다.

가장 은 아도가쉬방법은을 사용하는 일 것입니다.DUMP:

SELECT COUNT(DISTINCT DUMP(hour)) AS distinct_count
FROM hours;

출력: 3

DB Fidle 데모

아.. 숙제.이렇게 간단하지 않습니까?

SELECT COUNT(hour) 
  FROM hours

NULL은 카운트되지 않습니다.

알겠습니다! 요구사항을 제대로 읽지 못해서 죄송합니다.

SELECT COUNT(DISTINCT COALESCE(hour,-1)) 
  FROM hours

언급URL : https://stackoverflow.com/questions/15040602/counting-null-values-as-unique-value

반응형