2015-02-05 4 views
0

В приведенной ниже запрос возвращает точную информацию, я просто не везло, пытаясь сделать это:Pending Ежемесячный SQL Считает

1) Более динамичный, так что я не повторять одну и ту же строку кода каждый месяц

2) отформатированный по-разному, так что всего 2 столбцы месяца + года необходимы для просмотра отложенных отсчетов по FIELD1 + FIELD2

Пример коды (в основном, сумма, когда (ОТКРЫТАЯ дата до/в последний день месяца) и (ЗАКРЫТЬ дата наступает после месяца ИЛИ она все еще открыта)

SELECT 
SUM(CAST(case when OPENDATE <= '2014-11-30 23:59:59' 
     and ((CLOSED >= '2014-12-01') 
      or (CLOSED is null)) then '1' else '0' end as int)) Nov14  
,SUM(CAST(case when OPENDATE <= '2014-12-31 23:59:59' 
     and ((CLOSED >= '2015-01-01') 
      or (CLOSED is null)) then '1' else '0' end as int)) Dec14   
,SUM(CAST(case when OPENDATE <= '2015-01-30 23:59:59' 
     and ((CLOSED >= '2015-02-01') 
      or (CLOSED is null)) then '1' else '0' end as int)) Jan15 
,FIELD1,FIELD2 
FROM T 
GROUP BY FIELD1,FIELD2 

Результаты:

FIELD1 FIELD2 NOV14 DEC14 JAN15 
A  A  2  5  7 
A  B  6  8  4 
C  A  5  6  5 

...

Вместо:

COUNT FIELD1 FIELD2 MO YR 
14  A  A  12 2014  
18  A  B  12 2014    
16  C  A  1 2015  

...

Есть ли способ, чтобы получить это в одном кадре? Извините, если это повторяющаяся тема, я просмотрел некоторые доски, и они помогли мне получить закрытие счета ... но используя диапазон между двумя полями даты, мне не повезло.

Заранее спасибо

+1

Можете ли вы добавить еще образец ввода и требуемый выход? и создать 'sqlfiddle.com'demo? –

ответ

0

Один из способов сделать это - использовать table of numbers или calendar table. В приведенном ниже таблице Numbers имеет столбец Number, который содержит целые числа, начиная с 1. Существует много способов для generate such table. Вы можете сделать это на лету или иметь фактический стол. Я лично имею такую ​​таблицу в базе данных со 100 000 строк.

Первый CROSS APPLY эффективно создает столбец CurrentMonth, так что мне не нужно повторять звонок до DATEADD много раз позже.

Второй CROSS APPLY - это ваш запрос, который вы хотите запустить за каждый месяц. Он может быть настолько сложным, насколько это необходимо, он может возвращать более одной строки, если это необходимо.

-- Start and end dates should be the first day of the month 
DECLARE @StartDate date = '20141201'; 
DECLARE @EndDate date = '20150201'; 

SELECT 
    CurrentMonth 
    ,FIELD1 
    ,FIELD2 
    ,Counts 
FROM 
    Numbers 
    CROSS APPLY 
    (
     SELECT DATEADD(month, Numbers.Number-1, @StartDate) AS CurrentMonth 
    ) AS CA_Month 
    CROSS APPLY 
    (
     SELECT 
      FIELD1 
      ,FIELD2 
      ,COUNT(*) AS Counts 
     FROM T 
     WHERE 
      OPENDATE < CurrentMonth 
      AND (CLOSED >= CurrentMonth OR CLOSED IS NULL) 
     GROUP BY 
      FIELD1 
      ,FIELD2 
    ) AS CA 
WHERE 
    Numbers.Number < DATEDIFF(month, @StartDate, @EndDate) + 1 
; 

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

Решение написано на SQL Server 2008.

0

Как это:

SELECT 
FIELD1,FIELD2,datepart(month, OPENDATE), datepart(year, OPENDATE), sum(1) 
FROM T 
GROUP BY FIELD1,FIELD2, datepart(month, OPENDATE), datepart(year, OPENDATE) 

Но это, конечно, только на основе OPENDATE, если вам нужно иметь то же самое рассчитано на несколько месяцев, что будет сложнее , и вам, вероятно, понадобится календарная «таблица», которую вам придется пересекать, применяя эти данные.

Смежные вопросы