Запрос не возвращает все результаты

У меня есть 881 строка, которые должен вернуть запрос ниже, но возвращает только 744:

SELECT MIN(DateTime),AVG(ISNULL((Convert(decimal(10,3),SCR1_EXHAUST_GAS_TEMP)),0))
FROM jmusa_LOG1
GROUP BY DATEPART(HH,DateTime),DATEPART(DD,DateTime)
ORDER BY MIN(DateTime)

Теперь, если я выполню эти два запроса отдельно, я получу 588 и 293, соответственно, что равно 881, которые мне нужны:

SELECT MIN(DateTime),AVG(ISNULL((Convert(decimal(10,3),SCR1_EXHAUST_GAS_TEMP)),0))
FROM jmusa_LOG1
WHERE SCR1_EXHAUST_GAS_TEMP IS NULL
GROUP BY DATEPART(HH,DateTime),DATEPART(DD,DateTime)
ORDER BY MIN(DateTime)

Ключевым отличием в приведенном выше запросе является оператор WHERE.

SELECT MIN(DateTime),AVG(ISNULL((Convert(decimal(10,3),SCR1_EXHAUST_GAS_TEMP)),0))
FROM jmusa_LOG1
WHERE SCR1_EXHAUST_GAS_TEMP IS NOT NULL
GROUP BY DATEPART(HH,DateTime),DATEPART(DD,DateTime)
ORDER BY MIN(DateTime)

Здесь также имеется то же самое ключевое различие, только обратите внимание на разницу в том, что в одном случае IS NULL, а в другом IS NOT NULL.

**Кто-нибудь знает, почему это происходит? И каковы мои возможные ошибки, из-за которых первый упомянутый запрос не возвращает все 881 результат?

Менеджер БД: SQL Server 2008 R2, и SSMS Формат даты (если необходимо): YYYY-MM-DD HH:MM:SS.000

У вас есть комбинации из:

DATEPART(HH,DateTime),DATEPART(DD,DateTime)

где DATEPART(HH,DateTime),DATEPART(DD,DateTime) принимают значения как NULL, так и не NULL.

Другими словами, группы, определенные двумя отдельными запросами, пересекаются.

Комментарии (5)

Вы действительно уверены, что комбинация HH, DD и NULL(SCR1_EXHAUST) уникальна?

Если две строки, даже если они имеют разные DateTime, все же имеют одинаковые HH и DD, и одна из них имеет NULL SCR1_EXHAUST_GAS_TEMP, а другая не имеет NULL, GROUP BY объединит их в одну строку.

В этом случае вам нужно будет сгруппировать и по ISNULL(SCR1_EXHAUST_GAS_TEMP).

SELECT MIN(DateTime),AVG(ISNULL((Convert(decimal(10,3),SCR1_EXHAUST_GAS_TEMP)),0))
FROM jmusa_LOG1
GROUP BY ISNULL(SCR1_EXHAUST_GAS_TEMP, 0)=0, DATEPART(HH,DateTime),DATEPART(DD,DateTime)
ORDER BY MIN(DateTime)

...или, возможно, 744 строки - это то, что вам нужно.

Теперь, если вы хотите увидеть все даты, но для некоторых из них у вас есть нежелательные значения, то вам нужно:

  • подготовить первый набор, извлекая отдельные значения YYYY, MM, DD, HH, и это будет ваш "календарь"
  • подготовить второй набор, в котором вы будете усреднять ненулевые значения temp, группируя по YYYY, MM, DD и HH
  • LEFT JOIN календарь с данными, соединяясь по YYYY, MM, DD и HH и получая их, плюс TEMP, и упорядочивая по y, m, d, h.

Это даст вам что-то вроде,


Year Mo Da HH Temp
2012 07 07 00  750
2012 07 07 01  633
2012 07 07 02  NULL    
Комментарии (6)

следующий запрос должен показать вам линии, которые пересекаются в ваших двух наборах:

SELECT DATEPART(HH,DateTime),DATEPART(DD,DateTime)
FROM jmusa_LOG1
WHERE SCR1_EXHAUST_GAS_TEMP IS NULL
GROUP BY DATEPART(HH,DateTime),DATEPART(DD,DateTime)

intersect

SELECT DATEPART(HH,DateTime),DATEPART(DD,DateTime)
FROM jmusa_LOG1
WHERE SCR1_EXHAUST_GAS_TEMP IS NOT NULL
GROUP BY DATEPART(HH,DateTime),DATEPART(DD,DateTime)
Комментарии (10)