68

列を持つテーブルがありprocessed_timestampます。レコードが処理された場合、そのフィールドには処理された日時が含まれます。それ以外の場合は null です。

2 つの行を返すクエリを書きたいと思います。

NULL        xx -- count of records with null timestamps
NOT NULL    yy -- count of records with non-null timestamps

それは可能ですか?

更新:テーブルは非常に大きいため、効率が重要です。2 つのクエリを実行してそれぞれの合計を個別に計算することもできますが、できればテーブルに 2 回アクセスすることは避けたいと考えています。

4

14 に答える 14

53

MySQLでは、次のようなことができます

SELECT 
    IF(ISNULL(processed_timestamp), 'NULL', 'NOT NULL') as myfield, 
    COUNT(*) 
FROM mytable 
GROUP BY myfield
于 2008-10-27T10:53:03.143 に答える
45

T-SQL (MS SQL Server) では、次のように動作します。

SELECT
  CASE WHEN Field IS NULL THEN 'NULL' ELSE 'NOT NULL' END FieldContent,
  COUNT(*) FieldCount
FROM
  TheTable
GROUP BY
  CASE WHEN Field IS NULL THEN 'NULL' ELSE 'NOT NULL' END
于 2008-10-27T10:57:11.123 に答える
28

オラクル:

nvl2(field, 'NOT NULL', 'NULL') によるグループ化

于 2008-10-27T10:56:10.313 に答える
25

以下を試してください。ベンダー中立です。

select
    'null    ' as type,
    count(*)   as quant
    from       tbl
    where      tmstmp is null
union all
select
    'not null' as type,
    count(*)   as quant
    from       tbl
    where      tmstmp is not null

地元の DB2 グルにこれを見てもらった後、彼は同意します。これまでに提示されたソリューション (これを含む) のいずれも、(タイムスタンプにインデックスが作成されていない場合はテーブルの、そうでない場合はインデックスの) 完全なテーブル スキャンを回避することはできません。それらはすべて、テーブル内のすべてのレコードを 1 回だけスキャンします。

すべての CASE/IF/NVL2() ソリューションは、行ごとに null から文字列への変換を行うため、DBMS に不要な負荷がかかります。このソリューションにはその問題はありません。

于 2008-10-27T10:54:19.910 に答える
6

スチュワート、

たぶん、この解決策を検討してください。これは (また!) ベンダー固有ではありません。

SELECT count([processed_timestamp]) AS notnullrows, 
       count(*) - count([processed_timestamp]) AS nullrows 
FROM table

効率に関して言えば、結果を 1 行に含めることで、2 回のインデックス シーク/テーブル スキャンなどを回避できます。結果に 2 つの行が絶対に必要な場合は、集計の和集合のために、セットに対する 2 つのパスが避けられない場合があります。

お役に立てれば

于 2008-10-27T13:20:12.423 に答える
5

オラクルの場合は、次のことができます。

select decode(field,NULL,'NULL','NOT NULL'), count(*)
from table
group by decode(field,NULL,'NULL','NOT NULL');

他のDBでも同様のトリックが可能だと確信しています。

于 2008-10-27T10:53:51.067 に答える
3

MySQL のもう 1 つの方法は、CASE演算子を使用することです。これは、 よりも多くの選択肢に一般化できますIF()

SELECT CASE WHEN processed_timestamp IS NULL THEN 'NULL' 
            ELSE 'NOT NULL' END AS a,
       COUNT(*) AS n 
       FROM logs 
       GROUP BY a
于 2008-10-27T11:03:07.180 に答える
2

SQL Server (2012 以降):

SELECT IIF(ISDATE(processed_timestamp) = 0, 'NULL', 'NON NULL'), COUNT(*)
FROM MyTable
GROUP BY ISDATE(processed_timestamp);
于 2016-02-23T12:14:38.697 に答える
2

T-sql (sql-server) の別の方法

select  count(case when t.timestamps is null 
                    then 1 
                    else null end) NULLROWS,
        count(case when t.timestamps is not null 
                    then 1 
                    else null end) NOTNULLROWS
from myTable t 
于 2016-03-03T05:46:35.773 に答える
1

データベースにテーブル用の効率的な COUNT(*) 関数がある場合、小さい方の数を COUNT して減算することができます。

于 2008-10-28T02:49:34.880 に答える
0

[T-SQL]:

select [case], count(*) tally
from (
  select 
  case when [processed_timestamp] is null then 'null'
  else 'not null'
  end [case]
  from myTable
) a 

また、パーティションを形成する他の値をcaseステートメントに追加できます。たとえば、今日、昨日の正午から午後2時まで、木曜日の午後6時以降です。

于 2008-10-27T12:36:27.473 に答える
0
Select Sum(Case When processed_timestamp IS NULL
                         Then 1
                         Else 0
                 End)                                                               not_processed_count,
          Sum(Case When processed_timestamp Is Not NULL
                         Then 1
                         Else 0
                 End)                                                               processed_count,
          Count(1)                                                                total
From table

編集:注意深く読んでいませんでした、これは単一の行を返します。

于 2008-10-27T13:56:27.827 に答える
0

個人的には Pax のソリューションが気に入っていますが、どうしても 1 行だけを返す必要がある場合 (最近のように)、MS SQL Server 2005/2008 では、CTE を使用して 2 つのクエリを「スタック」できます。

with NullRows (countOf)
AS
(
    SELECT count(*) 
    FORM table 
    WHERE [processed_timestamp] IS NOT NULL
)
SELECT count(*) AS nulls, countOf
FROM table, NullRows
WHERE [processed_timestamp] IS NULL
GROUP BY countOf

お役に立てれば

于 2008-10-27T11:05:48.873 に答える
0

オラクルでは

SELECT COUNT(*), COUNT(TIME_STAMP_COLUMN)
FROM TABLE;

count(*) は、すべての行の数を返します

count(column_name) は NULL ではない行の数を返すので、

SELECT COUNT(*) - COUNT(TIME_STAMP_COLUMN) NUL_COUNT,
                  COUNT(TIME_STAMP_COLUMN) NON_NUL_COUNT
FROM TABLE

仕事をするべきです。

列にインデックスが付けられている場合、ある種の範囲スキャンが発生し、実際にテーブルを読み取らなくなる可能性があります。

于 2008-10-28T02:48:30.077 に答える