How do I return my records grouped by NULL and NOT NULL?

前端 未结 14 931
说谎
说谎 2021-01-30 16:24

I have a table that has a processed_timestamp column -- if a record has been processed then that field contains the datetime it was processed, otherwise it is null.

相关标签:
14条回答
  • 2021-01-30 16:26

    Try the following, it's vendor-neutral:

    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
    

    After having our local DB2 guru look at this, he concurs: none of the solutions presented to date (including this one) can avoid a full table scan (of the table if timestamp is not indexed, or of the indexotherwise). They all scan every record in the table exactly once.

    All the CASE/IF/NVL2() solutions do a null-to-string conversion for each row, introducing unnecessary load on the DBMS. This solution does not have that problem.

    0 讨论(0)
  • 2021-01-30 16:29

    In Oracle

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

    count(*) returns the count of all rows

    count(column_name) returns the number of rows which are not NULL, so

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

    ought to do the job.

    If the column is indexed, you might end up with some sort of range scan and avoid actually reading the table.

    0 讨论(0)
  • 2021-01-30 16:30

    I personally like Pax's solution, but if you absolutely require only one row returned (as I had recently), In MS SQL Server 2005/2008 you can "stack" the two queries using a CTE

    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
    

    Hope this helps

    0 讨论(0)
  • 2021-01-30 16:31

    [T-SQL]:

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

    And you can add into the case statement whatever other values you'd like to form a partition, e.g. today, yesterday, between noon and 2pm, after 6pm on a Thursday.

    0 讨论(0)
  • 2021-01-30 16:33

    Oracle:

    group by nvl2(field, 'NOT NULL', 'NULL')

    0 讨论(0)
  • 2021-01-30 16:34

    If it's oracle then you can do:

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

    I'm sure that other DBs allow for similar trick.

    0 讨论(0)
提交回复
热议问题