Два вопроса о моем скрипте SQL.Как добавить промежуточные / итоговые строки и проблему сортировки - PullRequest
0 голосов
/ 20 октября 2010

У меня есть некоторый T-SQL, который генерирует хороший отчет, в котором содержится сводная информация по месяцам.

У меня есть 2 вопроса, есть ли способ отсортировать месяцы по календарному порядку, а не по альфа? И что я хотел бы сделать, это добавить итоговую строку для каждого года и итоговую строку для всего отчета?

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(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

1 Ответ

2 голосов
/ 20 октября 2010

Для заказа по месяцам используйте:

  ORDER BY DATEPART(Month,Created) ASC

DatePart() возвращает целое число для части, указанной 1 для января, 2 для февраля и т. Д.


Вам может помочь SQL с функциями COALESCE () и ISNULL (). Это так же, как ваш первый выбор:

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

Я думаю, что в вашем выборе есть ошибка, я думаю, что ваша последняя строка должна быть такой:

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

Но я должен проверить это, чтобы быть уверенным.


Добавление в свертку трудно сделать - обычно это делается внешне для SQL в элементе управления или для отображения результатов. Вы могли бы сделать что-то вроде этого (надуманный пример):

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

или вы не можете иметь «дополнительный» столбец итогов и поместить его в столбец суммы.

...