Если вы используете SQL Server 2005 or above
, вы могли бы использовать Common Table Expressions (CTE)
, чтобы получить желаемый результат. Ниже приведен пример того, как вы можете получить результаты, как описано в вопросе.
Click here to view the demo in SQL Fiddle.
Описание:
- Создание и вставка операторы создают таблицу и заполнит с некоторыми образцами данных. Я создал таблицу на основе запроса, заданного в вопросе.
- Утверждение в предложении WITH выполняет рекурсивное выражение. В этом случае
SELECT
выше UNION ALL
получают минимальные и максимальные сроки, доступные в таблице dbo.countproject
- После того, как минимальная дата забирается, то второе ЗЕЬЕСТ после UNION ALL увеличивает срок в 1 месяц с интервалом до момента рекурсивное выражение достигает максимальной даты, доступной в таблице.
- Рекурсивный CTE предоставил все возможные даты.Этот вывод доступен в таблице с именем alltransactions.
- Мы должны присоединиться к этому выходу CTE
alltransactions
с фактическим столом countproject
с использованием LEFT OUTER JOIN
, так как мы хотим показать все годы и месяцы, даже если транзакций нет.
- Таблицы
alltransactions
и countproject
соединяются на год и месяц части даты. Затем запрос применяет необходимые фильтры в разделе WHERE, а затем группирует данные по годам и месяцам, прежде чем заказывать его по годам и месяцам.
- Из данных примера можно указать, что самая ранняя дата в таблице -
2004-07-01
, а последняя дата - 2005-12-01
. Следовательно, выпуск показывает с 2004 года/месяц 07 по 2005 год/месяц 12.
Надеюсь, что это поможет.
Script:
CREATE TABLE dbo.countproject
(
id INT NOT NULL IDENTITY
, trans_date DATETIME NOT NULL
, make_name VARCHAR(20) NOT NULL
, model_name VARCHAR(20) NOT NULL
, type VARCHAR(20) NOT NULL
, trans_type VARCHAR(20) NOT NULL
, mfr INT NOT NULL
);
INSERT INTO dbo.countproject (trans_date, make_name, model_name, type, trans_type, mfr) VALUES
('1900-01-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('1900-01-01', 'Toyota', 'Corolla', 'Sale', 'EU', 2000),
('2004-07-01', 'Nissan', 'Altima', 'Sale', 'EU', 2000),
('2005-12-01', 'Toyota', 'Camry', 'Sale', 'EU', 2000),
('2004-04-01', 'Ford', 'Focus', 'Sale', 'EU', 2000),
('2005-08-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2005-11-01', 'Toyota', 'Camry', 'Sale', 'EU', 2000),
('2004-08-01', 'Toyota', 'Corolla', 'Sale', 'EU', 2000),
('2005-12-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2004-07-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2004-11-01', 'Honda', 'Civic', 'Sale', 'EU', 2000),
('2005-08-01', 'Honda', 'Civic', 'Sale', 'EU', 2000);
;WITH alltransactions
AS
(
SELECT MIN(trans_date) AS continuousdate
, MAX(trans_date) AS maximumdate
FROM dbo.countproject
WHERE trans_date <> '1900-01-01'
UNION ALL
SELECT DATEADD(MONTH, 1, continuousdate) AS continuousdate
, maximumdate
FROM alltransactions
WHERE DATEADD(MONTH, 1, continuousdate) <= maximumdate
)
SELECT YEAR(at.continuousdate) AS [Year]
, MONTH(at.continuousdate) AS [Month]
, COUNT(cp.trans_date) AS [Count]
FROM alltransactions at
LEFT OUTER JOIN countproject cp
ON YEAR(at.continuousdate) = YEAR(cp.trans_date)
AND MONTH(at.continuousdate) = MONTH(cp.trans_date)
AND cp.make_name = 'Honda'
and cp.model_name = 'Civic'
and cp.type = 'Sale'
and cp.trans_type LIKE '%EU'
and cp.mfr = '2000'
GROUP BY YEAR(at.continuousdate)
, MONTH(at.continuousdate)
ORDER BY [Year]
, [Month];
Выход:
Year Month Count
----- ------ -----
2004 4 0
2004 5 0
2004 6 0
2004 7 1
2004 8 0
2004 9 0
2004 10 0
2004 11 1
2004 12 0
2005 1 0
2005 2 0
2005 3 0
2005 4 1
2005 5 0
2005 6 0
2005 7 0
2005 8 2
2005 9 0
2005 10 0
2005 11 0
2005 12 1
Какое поле конкретно обнуляемым? поле 'trans_date' или что-то еще? –
http://stackoverflow.com/questions/1478951/tsql-generate-a-resultset-of-incrementing-dates –