Подтвердить что ты не робот

Как вернуть мои записи, сгруппированные по NULL и NOT NULL?

У меня есть таблица с столбцом processed_timestamp - если запись была обработана, то это поле содержит время, которое было обработано, в противном случае оно равно null.

Я хочу написать запрос, который возвращает две строки:

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

Возможно ли это?

Обновление: Таблица довольно большая, поэтому эффективность важна. Я мог бы просто запустить два запроса, чтобы вычислить каждую общую сумму отдельно, но я хочу, чтобы избежать удара по таблице дважды, если я могу избежать этого.

4b9b3361

Ответ 1

Oracle:

группа по nvl2 (поле "NOT NULL", "NULL" )

Ответ 2

В MySQL вы можете сделать что-то вроде

SELECT 
    IF(ISNULL(processed_timestamp), 'NULL', 'NOT NULL') as myfield, 
    COUNT(*) 
FROM mytable 
GROUP BY myfield

Ответ 3

В 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

Ответ 4

Попробуйте следующее: оно нейтрально:

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 посмотрит на это, он соглашается: ни один из представленных на сегодняшний день решений (включая этот) не позволяет полностью сканировать таблицу (таблицы, если временная метка не проиндексирована, или индекса в другой). Все они сканируют каждую запись в таблице ровно один раз.

Все решения CASE/IF/NVL2() выполняют преобразование от нуля до строки для каждой строки, вводя ненужную нагрузку на СУБД. Это решение не имеет этой проблемы.

Ответ 5

Если это оракул, вы можете сделать:

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

Я уверен, что другие БД допускают подобный трюк.

Ответ 6

Стюарт,

Возможно, рассмотрим это решение. Это (также!) Поставщик неспецифичен.

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

Что касается эффективности, это позволяет избежать двукратного поиска индекса/таблицы/независимо от включения результатов в одну строку. Если вам абсолютно требуется 2 строки в результате, два прохода над множеством могут быть неизбежными из-за объединения агрегатов.

Надеюсь, что это поможет

Ответ 7

Если ваша база данных имеет эффективную функцию COUNT (*) для таблицы, вы можете использовать COUNT в зависимости от того, какое меньшее число и вычесть.

Ответ 8

SQL Server (начиная с 2012 года):

SELECT IIF(ISDATE(processed_timestamp) = 0, 'NULL', 'NON NULL'), COUNT(*)
FROM MyTable
GROUP BY ISDATE(processed_timestamp);

Ответ 9

Другой метод MySQL - использовать 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

Ответ 10

Мне лично нравится решение 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

Надеюсь, что это поможет

Ответ 11

[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 любые другие значения, которые хотите создать раздел, например. сегодня, вчера, между полуднем и 2pm, после 18:00 в четверг.

Ответ 12

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

Изменить: не читал внимательно, этот возвращает одну строку.

Ответ 13

В Oracle

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

должен выполнить эту работу.

Если столбец проиндексирован, вы можете провести некоторое сканирование диапазона и избежать фактического чтения таблицы.

Ответ 14

Другой способ в 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