ここで、注意が必要なことがいくつかあります。まず、言及したように、COUNT クエリは、決して NULL ではない i.column_name の値を使用して実行されます。
次に、値に関係なく、句の条件に一致する行COUNT(*)
の数を返します。特定の列にある値の数を数えたい場合は、その列の値を明示的に指定する必要があります。WHERE
NULL
NOT NULL
COUNT
次の例を参照してください ( SQL Fiddle ):
Oracle 11g R2 スキーマのセットアップ:
CREATE TABLE null_col_vals (
col_without_nulls INTEGER NOT NULL
, col_with_nulls INTEGER
, col_with_mix INTEGER
)
/
INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, NULL)
/
INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, 1)
/
INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, NULL)
/
クエリ 1 :
SELECT
COUNT(col_without_nulls) col_without_nulls
, COUNT(col_with_nulls) col_with_nulls
, COUNT(col_with_mix) col_with_mix
, COUNT(*) all_rows
FROM null_col_vals
結果:
| COL_WITHOUT_NULLS | COL_WITH_NULLS | COL_WITH_MIX | ALL_ROWS |
----------------------------------------------------------------
| 3 | 0 | 1 | 3 |
ご覧のとおり、常に存在する行数を返しますが、他のものは、指定された列に値が存在するCOUNT(*)
かどうかによって結果が異なります。NULL
EXECUTE IMMEDIATE
を使用して、列名をクエリの一部に変換する必要があります。このようなものは仕事をするかもしれません:
クエリ 2 :
DECLARE
l_count INTEGER;
BEGIN
FOR r_col IN (
SELECT *
FROM all_tab_columns atc
WHERE atc.table_name = 'NULL_COL_VALS'
)
LOOP
dbms_output.put_line(r_col.column_name);
EXECUTE IMMEDIATE 'SELECT COUNT(' || r_col.column_name || ') FROM null_col_vals'
INTO l_count;
dbms_output.put_line(l_count);
END LOOP;
END;