DECLARE
@StartDate datetime,
@EndDate datetime;
SET @StartDate = '20101115';
SET @EndDate = '20101205';
WITH Mos AS (
SELECT
Number,
DateAdd(Month, Number, @StartDate - Day(@StartDate) + 1) MoDate
FROM master.dbo.spt_values
WHERE
Type = 'P'
AND Number <= DateDiff(Month, @StartDate, @EndDate)
), Dys AS (
SELECT
MoDate,
DateDiff(
Day,
CASE WHEN Number = 0 THEN @StartDate ELSE MoDate END,
CASE WHEN Number = DateDiff(Month, @StartDate, @EndDate) THEN @EndDate ELSE DateAdd(Month, 1, MoDate) - 1 END
) + 1 Cnt
FROM Mos
)
SELECT
Year(MoDate) Yr,
Coalesce(DateName(Month, MoDate), 'Total') Mo,
Convert(varchar(11), Sum(Cnt)) + ' day' + CASE WHEN Sum(Cnt) = 1 THEN '' ELSE 's' END Descr
FROM Dys
GROUP BY MoDate
WITH ROLLUP
ORDER BY Grouping(MoDate), MoDate;
Và đây là một phiên bản bảng trong trường hợp bạn muốn làm điều đó với nhiều cùng một lúc:
CREATE TABLE AccountDates (
AccountCode varchar(10) NOT NULL CONSTRAINT PK_AccountDates PRIMARY KEY CLUSTERED,
StartDate datetime,
EndDate datetime
);
INSERT AccountDates VALUES ('BLINKEN', '20101115', '20101205');
INSERT AccountDates VALUES ('KRAM', '20101027', '20110118');
INSERT AccountDates VALUES ('NUVU', '20101207', '20101207');
WITH Mos AS (
SELECT
AccountCode,
D.StartDate,
D.EndDate,
Number,
DateAdd(Month, Number, D.StartDate - Day(D.StartDate) + 1) MoDate
FROM
AccountDates D
INNER JOIN master.dbo.spt_values V ON V.Number <= DateDiff(Month, D.StartDate, D.EndDate)
WHERE
V.Type = 'P'
), Dys AS (
SELECT
AccountCode,
MoDate,
DateDiff(
Day,
CASE WHEN Number = 0 THEN StartDate ELSE MoDate END,
CASE WHEN Number = DateDiff(Month, StartDate, EndDate) THEN EndDate ELSE DateAdd(Month, 1, MoDate) - 1 END
) + 1 Cnt
FROM Mos
)
SELECT
AccountCode,
Year(MoDate) Yr,
Coalesce(DateName(Month, MoDate), 'Total') Mo,
Convert(varchar(11), Sum(Cnt)) + ' day' + CASE WHEN Sum(Cnt) = 1 THEN '' ELSE 's' END Descr
FROM Dys
GROUP BY AccountCode, MoDate
WITH ROLLUP
HAVING Grouping(AccountCode) = 0
ORDER BY
AccountCode,
Grouping(MoDate),
MoDate;
Tôi đã đơn giản hoá mọi thứ một chút so với truy vấn ban đầu của mình.
Chà, một số điều mặc khải! Tất nhiên, việc sử dụng bảng hệ thống sẽ phụ thuộc vào nhu cầu tạo và điền vào bảng của chúng ta. Nhưng điều chính đối với tôi ở đây là cách bạn đã chọn để đếm ngày. Tuyệt vời! Tôi đã đưa ra một phiên bản giống như những gì người khác đã đăng, nhưng bây giờ tôi xấu hổ để hiển thị nó: quá tầm thường! –
@Andriy - sẽ rất tuyệt nếu bạn upvoted câu trả lời :) – RichardTheKiwi
@cyberwiki: Rất đúng, xin lỗi. Nghĩ rằng tôi đã upvoted nó. Rất tốt đẹp của bạn để nhắc nhở tôi về ý định của riêng tôi. :) –