Сделайте запрос Count (), верните 0 вместо пустого - PullRequest
3 голосов
/ 30 июля 2009

У меня есть отчет, который отслеживает, как долго определенные элементы были в базе данных, и делает это, отслеживая его по ряду возрастных диапазонов (20-44, 45-60, 61-90, 91-180, 180+ ). У меня есть следующий запрос в качестве источника данных отчета:

SELECT DISTINCT Source.ItemName, 
Count(SELECT Source.DateAdded FROM Source WHERE Int(Date()-Source.DateAdded) > 20) AS Total, 
Count(SELECT Source.DateAdded FROM Source WHERE Int(Date()-Source.DateAdded) BETWEEN 20 AND 44) AS BTWN_20_44, 
Count(SELECT Source.DateAdded FROM Source WHERE Int(Date()-Source.DateAdded) BETWEEN 45 AND 60) AS BTWN_45_60, 
Count(SELECT Source.DateAdded FROM Source WHERE Int(Date()-Source.DateAdded) BETWEEN 61 AND 90) AS BTWN_61_90, 
Count(SELECT Source.DateAdded FROM Source WHERE Int(Date()-Source.DateAdded) BETWEEN 91 AND 180) AS BTWN_91_180, 
Count(SELECT Source.DateAdded FROM Source WHERE Int(Date()-Source.DateAdded) > 180) AS GT_180
FROM Source
GROUP BY Source.ItemName;

Этот запрос отлично работает, за исключением случаев, когда в столбце нет записей. Вместо того, чтобы возвращать счетчик 0, возвращается пустое значение.

Как мне заставить Count () вернуть 0 вместо пустого?

Ответы [ 4 ]

9 голосов
/ 30 июля 2009

Вы можете вернуть

ISNULL(Count(......), 0)

и все должно быть в порядке - будет в MS SQL Server - но я только что видел, что вы используете Access. Поскольку я недостаточно знаю Access, я не уверен, что это сработает - можете ли вы попробовать?

ОК - рад видеть, что в Access есть нечто похожее (если не совсем то же, что и в SQL Server).

Марк

1 голос
/ 01 августа 2009

На секунду, хотя (без дополнительной информации) я думаю, что вы делаете этот запрос очень неправильно ....

Как я уже сказал, когда я пытаюсь выполнить исходный запрос, я получаю сообщение об ошибке "Максимально одна запись может быть возвращена этим подзапросом".

Это, вероятно, немного ближе к тому, что вы хотите

SELECT DISTINCT Source.ItemName, 
    (SELECT count(Source.DateAdded ) FROM Source 
        WHERE Int(Date()-Source.DateAdded)> 20)  AS Total, 
    (SELECT count(Source.DateAdded ) FROM Source  
        WHERE Int(Date()-Source.DateAdded) BETWEEN 20 AND 44) AS BTWN_20_44, 
    (SELECT count(Source.DateAdded ) FROM Source  
        WHERE Int(Date()-Source.DateAdded) BETWEEN 45 AND 60) AS BTWN_45_60, 
    (SELECT count(Source.DateAdded ) FROM Source  
        WHERE Int(Date()-Source.DateAdded) BETWEEN 61 AND 90) AS BTWN_61_90, 
    (SELECT count(Source.DateAdded ) FROM Source  
        WHERE Int(Date()-Source.DateAdded) BETWEEN 91 AND 180) AS BTWN_91_180, 
    (SELECT count(Source.DateAdded ) FROM Source  
        WHERE Int(Date()-Source.DateAdded) > 180) AS GT_180
FROM Source
GROUP BY Source.ItemName;

Если вы не пытаетесь подсчитать количество наименований предметов ... в этом случае это немного сложнее.

1 голос
/ 31 июля 2009

Еще лучше, используйте Nz(), например.

Nz(Count(SELECT Source.DateAdded 
            FROM Source 
            WHERE Int(Date()-Source.DateAdded), 0)

Возвращает 0, если результат равен нулю, или рассчитывает иначе.

Обратите внимание, что функция Nz() является частью объектной модели Access и поэтому доступна только при использовании в пользовательском интерфейсе Access. Если вы используете ядро ​​базы данных Access без интерфейса доступа (из другого приложения через OLE DB, ODBC и т. Д.), Вы получите сообщение об ошибке «Неопределенная функция« Nz »в выражении».

0 голосов
/ 30 июля 2009

Заменить операторы Count на

Sum(Iif(DateDiff("d",DateAdded,Date())>=91,Iif(DateDiff("d",DateAdded,Date())<=180,'1','0'),'0')) AS BTWN_91_180,

Я не фанат вложенных Iif s, но, похоже, нет никакого пути к ним, поскольку DateDiff и BETWEEN...AND не играли хорошо.

Чтобы удалить ItemName s без каких-либо добавленных дат, блок запроса должен был быть заключен в запрос большего размера, поскольку проверка по вычисляемому полю не может быть выполнена изнутри запроса. Конечный результат этого запроса:

SELECT *
FROM 
     (
     SELECT DISTINCT Source.ItemName AS InvestmentManager, 
     Sum(Iif(DateDiff("d",DateAdded,Date())>=20,Iif(DateDiff("d",DateAdded,Date())<=44,'1','0'),'0')) AS BTWN_20_44,
     Sum(Iif(DateDiff("d",DateAdded,Date())>=45,Iif(DateDiff("d",DateAdded,Date())<=60,'1','0'),'0')) AS BTWN_45_60,
     Sum(Iif(DateDiff("d",DateAdded,Date())>=61,Iif(DateDiff("d",DateAdded,Date())<=90,'1','0'),'0')) AS BTWN_61_90,
     Sum(Iif(DateDiff("d",DateAdded,Date())>=91,Iif(DateDiff("d",DateAdded,Date())<=180,'1','0'),'0')) AS BTWN_91_180,
     Sum(Iif(DateDiff("d",DateAdded,Date())>180,'1','0')) AS GT_180,
     Sum(Iif(DateDiff("d",DateAdded,Date())>=20,'1','0')) AS Total
     FROM Source
     WHERE CompleteState='FAILED'
     GROUP BY ItemName
     )
WHERE Total > 0;
...