23

次のように、列のさまざまな値をカウントする必要があります。

Hours
1
1
2
null
null
null

結果は次のようになります:3。私の質問は:

select count(distinct hour) from hours;

しかし、それは戻ります:2.私もテストしました:

select count(*) from hours group by hour

ただし、次の3つの行が返されます。

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

null値を1つの値としてカウントし、distinctを使用して、繰り返される値のカウントを回避するにはどうすればよいですか?

私は高度なSQLを学んでいます、彼らは私にすべてのソリューションのためのこれらの要件を望んでいます:

クエリを解決するために必要なサブクエリの数を最小限に抑えるようにしてください。さらに、次の構造を使用することは許可されていません。

  • FROMまたはSELECTでSELECTします。サブクエリを使用できます(WHEREまたはHAVINGでSELECT)
  • COUNT(COUNT。..))、SUM(COUNT。..))などの集計関数の組み合わせ。
  • あなたがそれを避けることができればUNION。
  • 非標準機能(NVLなど)
  • 場合
4

11 に答える 11

34
select  count(distinct col1) + count(distinct case when col1 is null then 1 end)
from    YourTable
于 2013-02-23T12:39:12.000 に答える
19

時間が数値の場合、整数のみになり得る場合:

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

それ以外の場合、浮動小数点になる可能性がある場合は、NULLをchar文字列に変更します。

例えば

select count(distinct coalesce(to_char(hour), 'a')) cnt from test;
于 2013-02-24T00:18:58.133 に答える
8
select 
   count(0) 
from
  (
      select distinct hour from hours
  )

SqlFiddle

于 2013-02-23T12:55:54.097 に答える
3
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 ;
于 2013-02-23T13:06:07.223 に答える
2

多分

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

しましょう?

于 2013-09-09T15:00:18.557 に答える
2
select count(distinct nvl(hour,0)) from hours;
于 2017-10-03T09:08:32.627 に答える
1

NVL()COALESCE()またはを使用するだけでより効率的なクエリを取得できることはほぼ確実であるため、要件はかなり奇妙だと思いますCASENULLただし、サブクエリのみを使用して、正しい結果を得ることができました(そして値の有無に対処できました)。私は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、2つの簡単な選択肢のいずれかを使用することです...次のいずれかです。

  1. TO_CHARNULL以外の値をデータ型VARCHAR2NVLに変換し、NULL値をVARCHAR2'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 |
于 2013-02-23T13:18:05.390 に答える
1

Andresによる回答は、要件を完全に満たし、以下以外の機能をまったく使用しないものCOUNTです。

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

私は別の目的で同じものを探していましたが(私は何でも使用できます)、これを見るまでは正しくも効率的でもありませんでした。Andresに感謝します。このような単純なソリューションでありながら強力なソリューションです。

于 2015-05-05T21:13:05.887 に答える
0

指定された基準に最も近いものは次のとおりです:( SQLFiddle

クエリ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の外部に存在するとは思わないので、これは質問の精神に反している可能性がありますが、少なくともリストされている基準には適合しています。

于 2013-02-23T22:21:53.323 に答える
0

おそらく最も簡単な方法は、以下を使用することDUMPです。

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

出力:3

DBFiddleデモ

于 2017-11-27T19:34:41.153 に答える
-1

ああ..宿題。こんなに簡単じゃないですか。

SELECT COUNT(hour) 
  FROM hours

NULLはカウントされません。

とった!要件を正しく読んでいないのは残念です。

SELECT COUNT(DISTINCT COALESCE(hour,-1)) 
  FROM hours
于 2013-02-23T16:36:45.930 に答える