开发者

Two questions about my SQL script. How to add subtotal/total lines, and a sorting issue

I have some T-SQL that generates a nice report giving a summary some stuff by month.

I have 2 questions, is there a way to get the to sort the months by calendar order, not by alpha? And, what i would like to do is add a total line for each year, and a total line for the whole report?

SELECT
    CASE WHEN tmpActivity.Year IS NULL THEN 
        CASE WHEN tmpCreated.Year IS NULL THEN
            CASE WHEN tmpContactsCreated.Year IS NULL THEN
                null
            ELSE tmpContactsCreated.Year END
        ELSE tmpCreated.Year END
    ELSE tmpActivity.Year END As Year, 

    CASE WHEN tmpActivity.Month IS NULL THEN 
        CASE WHEN tmpCreated.Month IS NULL THEN 
            CASE WHEN tmpContactsCreated.Month IS NULL THEN 
                null
            ELSE DateName(month, DateAdd(month, tmpContactsCreated.Month - 1, '1900-01-01' )) END
        ELSE DateName开发者_如何学Go(month, DateAdd(month, tmpCreated.Month - 1, '1900-01-01' )) END
    ELSE DateName(month, DateAdd(month, tmpActivity.Month - 1, '1900-01-01' )) END As Month, 

    CASE WHEN tmpActivity.ActiveAccounts IS NULL THEN 0 ELSE tmpActivity.ActiveAccounts END AS ActiveAccounts, 
    CASE WHEN tmpCreated.NewAccounts IS NULL THEN 0 ELSE tmpCreated.NewAccounts END AS NewAccounts, 
    CASE WHEN tmpContactsCreated.NewContacts IS NULL THEN 0 ELSE tmpContactsCreated.NewContacts END AS NewContacts
FROM
(
SELECT YEAR(LastLogon) As Year, MONTH(LastLogon) As Month, COUNT(*) As ActiveAccounts
FROM Users
WHERE LastLogon >= '1/1/1800'
GROUP BY YEAR(LastLogon), MONTH(LastLogon)
) as tmpActivity

FULL JOIN
(
SELECT YEAR(Created) As Year, MONTH(Created) As Month, COUNT(*) As NewAccounts
FROM Users
WHERE Created >= '1/1/1800'
GROUP BY YEAR(Created), MONTH(Created)
) as tmpCreated ON tmpCreated.Year = tmpActivity.Year AND tmpCreated.Month = tmpActivity.Month

FULL JOIN
(
SELECT YEAR(Created) As Year, MONTH(Created) As Month, COUNT(*) As NewContacts
FROM Contacts
WHERE Created >= '1/1/1800'
GROUP BY YEAR(Created), MONTH(Created)
) as tmpContactsCreated ON tmpContactsCreated.Year = tmpCreated.Year AND tmpContactsCreated.Month = tmpCreated.Month

Order By Year DESC, Month DESC


To order by the month use the following:

  ORDER BY DATEPART(Month,Created) ASC

DatePart() returns an integer for the part specified 1 for January, 2 for Febuary etc.


You're SQL could be helped with the COALESCE() and ISNULL() functions. This is the same as your first select:

SELECT
    COALESCE(tmpActivity.Year,tmpCreated.Year,tmpContactsCreated.Year) as Year, 
    COALESCE(tmpActivity.Month,tmpCreated.Month,tmpContactsCreated.Month) as Month,
    ISNULL(tmpActivity.ActiveAccounts,0) AS ActiveAccounts, 
    ISNULL(tmpCreated.NewAccounts,0) AS NewAccounts, 
    ISNULL(tmpContactsCreated.NewContacts,0) AS NewContacts

I think there is a bug in your select, I believe your last line has to be this:

) as tmpContactsCreated ON (tmpContactsCreated.Year = tmpCreated.Year AND tmpContactsCreated.Month = tmpCreated.Month) OR
                           (tmpContactsCreated.Year = tmpActivity.Year AND tmpContactsCreated.Month = tmpActivity.Month)     

But I would have to test this to be sure.


Adding in rollups is hard to do -- typically this is done externally to the SQL in the control or whatever displays the results. You could do something like this (contrived example):

SELECT 1 as reportOrder, date, amount, null as total
FROM invoices
UNION ALL
SELECT 2 , null, null, sum(amount)
FROM invoices
ORDER BY reportOrder, date

or you could not have the "extra" total column and put it in the amount column.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜