代码之家  ›  专栏  ›  技术社区  ›  Stewart Johnson

如何返回按NULL和NOTNULL分组的记录?

  •  48
  • Stewart Johnson  · 技术社区  · 16 年前

    processed_timestamp 列——如果记录已处理,则该字段包含处理该记录的日期时间,否则为空。

    我想编写一个返回两行的查询:

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

    更新: 桌子很大,所以效率很重要。我可以只运行两个查询来分别计算每个总数,但如果可以避免的话,我希望避免两次命中表。

    14 回复  |  直到 15 年前
        1
  •  52
  •   Stefan Gehrig    16 年前

    SELECT 
        IF(ISNULL(processed_timestamp), 'NULL', 'NOT NULL') as myfield, 
        COUNT(*) 
    FROM mytable 
    GROUP BY myfield
    
        2
  •  44
  •   Tomalak    16 年前

    在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
    
        3
  •  27
  •   trunkc    16 年前

    神谕:

    按nvl2分组(字段“非空”、“空”)

        4
  •  25
  •   paxdiablo    15 年前

    请尝试以下操作,它与供应商无关:

    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专家看了这一点之后,他表示同意:迄今为止提出的解决方案(包括这一个)都无法避免完整的表扫描(如果时间戳未被索引,则扫描表,或者以其他方式扫描索引)。他们都会精确地扫描表中的每条记录一次。

        5
  •  5
  •   ADEpt    16 年前

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

    我相信其他DBs也会采用类似的技巧。

        6
  •  5
  •   James Green    16 年前

    斯图尔特,

    也许考虑一下这个解决方案。它(也是!)供应商不特定。

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

    至于效率,通过将结果包含在一行中,可以避免2x索引查找/表扫描/任何操作。如果结果中绝对需要2行,则由于合并聚合,在集合上进行两次传递可能是不可避免的。

        7
  •  2
  •   Tom Gruff    16 年前

    CASE operator ,可以概括为比 IF() :

    SELECT CASE WHEN processed_timestamp IS NULL THEN 'NULL' 
                ELSE 'NOT NULL' END AS a,
           COUNT(*) AS n 
           FROM logs 
           GROUP BY a
    
        8
  •  2
  •   Refael    8 年前

    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 
    
        9
  •  1
  •   dkretz    16 年前

    如果您的数据库有一个表的有效计数(*)函数,则可以计算较小的数字,然后进行减法。

        10
  •  1
  •   Jatin Sanghvi    8 年前

    SQL Server(从2012年开始):

    SELECT IIF(ISDATE(processed_timestamp) = 0, 'NULL', 'NON NULL'), COUNT(*)
    FROM MyTable
    GROUP BY ISDATE(processed_timestamp);
    
        11
  •  0
  •   James Green    16 年前

    我个人喜欢Pax的解决方案,但如果您绝对只需要返回一行(正如我最近所做的),那么在MS SQL Server 2005/2008中,您可以使用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
    

    希望这有帮助

        12
  •  0
  •   Unsliced    16 年前

    [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点之后。

        13
  •  0
  •   Aleksey Otrubennikov    16 年前
    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
    

    编辑:没有仔细阅读,这一行只返回一行。

        14
  •  0
  •   EvilTeach    16 年前

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

    count(*)返回所有行的计数

    count(column_name)返回不为空的行数,因此

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

    我应该做这项工作。