2013-11-12 3 views
1

У меня есть следующий запрос:Group запрос каждый месяц

select 

(select Sum(Stores) from XYZ where Year = '2013' and Month = '8') 
- 
(select Sum(SalesStores) from ABC where Year = '2013' and Month = '8') as difference 

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

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

+0

creat e пользовательский взгляд с 12 месяцами в этом и сделайте Cartesian присоединиться к году, и это должно дать вам 12 месяцев за каждый год. – Santhosh

+0

Нет необходимости создавать представление –

ответ

2
;WITH Months(Month) AS 
(
    SELECT 1 
    UNION ALL 
    SELECT Month + 1 
    FROM Months 
    where Month < 12 
) 


SELECT '2013' [Year], m.Month, COALESCE(SUM(Stores), 0) - COALESCE(SUM(SalesStores), 0) [Difference] 
FROM months m 
LEFT JOIN XYZ x ON m.Month = x.Month 
LEFT JOIN ABC a ON a.Month = m.Month 

GROUP BY m.Month 
+1

Это правильная идея, но вы не должны использовать «внутреннее соединение» в том случае, если в течение некоторого месяца есть данные только по одной таблице. – Lamak

+0

«JOIN» ** ** «INNER JOIN». Вы должны использовать 'FULL JOIN' и иметь логику с' ISNULL' для 'SELECT' – Lamak

+0

@Lamak - ОП запросил запрос, который выполняется против каждого месяца в году. Либо или обе таблицы могут отсутствовать несколько месяцев. Для обеспечения результатов за каждый месяц требуется таблица чисел или другой источник месяцев. – HABO

1

Вы могли бы использовать в своих внутренних сделок GROUP BY, а затем запустить соединение, как это:

SELECT left.Month, (left.sum - COALESCE(right.sum, 0)) as difference 
FROM (
    SELECT Month, SUM(Stores) as sum 
    FROM XYZ WHERE Year = '2013' 
    GROUP BY Month 
) left 
LEFT OUTER JOIN (
    SELECT Month, SUM(Stores) as sum 
    FROM ABC WHERE Year = '2013' 
    GROUP BY Month 
) right ON left.Month = right.Months 

Обратите внимание на использование COALESCE. Он позволяет сохранить значение первого SUM в случае, если в таблице ABC нет записей за месяц.

+0

. Как и в предыдущем комментарии, вы не должны использовать 'INNER JOIN', но вместо этого« FULL JOIN ». во всяком случае, +1 – Lamak

+0

@Lamak Вы правы, это хорошая идея добавить туда внешнее соединение. Я также добавил 'COALESCE', чтобы не видеть« NULL », когда в' ABC' нет соответствующего месяца. Благодаря! – dasblinkenlight

2

Если есть месяц без данных/строк в XYZ или ABC таблиц, то я хотел бы использовать FULL OUTER JOIN:

SELECT ISNULL(x.[Month], y.[Month]) AS [Month], 
     ISNULL(x.Sum_Stores, 0) - ISNULL(y.Sum_SalesStores, 0) AS Difference 
FROM 
(
    SELECT [Month], Sum(Stores) AS Sum_Stores 
    FROM XYZ 
    WHERE [Year] = '2013' 
    GROUP BY [Month] 
) AS x 
FULL OUTER JOIN 
(
    SELECT [Month], Sum(SalesStores) AS Sum_SalesStores 
    FROM ABC 
    WHERE [Year] = '2013' 
    GROUP BY [Month] 
) AS y ON x.[Month] = y.[Month] 
0

В следующем примере используется UNION ALL оператора с КТРОМ

;WITH cte AS 
(SELECT SUM(Stores) AS Stores, [Month] 
    FROM dbo.XYZ 
    WHERE [Year] = '2013' 
    GROUP BY [Month]  
    UNION ALL 
    SELECT -1.00 * SUM(SalesStores), [Month] 
    FROM dbo.ABC  
    WHERE [Year] = '2013' 
    GROUP BY [Month] 
) 
    SELECT [Month], SUM(Stores) AS Difference 
    FROM cte 
    GROUP BY [Month] 

Demo на SQLFiddle

0
;WITH Months(Month) AS 
    (
     SELECT 1 
     UNION ALL 
     SELECT Month + 1 
     FROM Months 
     where Month < 12 
    ) 

    SELECT Months. Month , 
(select isnull(Sum(Stores),0) from XYZ where Year = '2013' and Month = Months.Month) - (select isnull(Sum(SalesStores),0) from ABC where Year = '2013' and Month =Months.Month) as difference 
    FROM Months 
Смежные вопросы