2010-10-20 5 views
0

J'ai un T-SQL qui génère un bon rapport donnant un résumé des choses par mois.Deux questions sur mon script SQL. Comment ajouter des lignes de sous-total/total, et un problème de tri

J'ai 2 questions, est-il un moyen d'obtenir le tri des mois par ordre de calendrier, pas par alpha? Et, ce que je voudrais faire est d'ajouter une ligne totale pour chaque année, et une ligne totale pour l'ensemble du rapport?

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 

Répondre

2

Pour commander par l'utilisation du mois qui suit:

ORDER BY DATEPART(Month,Created) ASC 

DatePart() retourne un entier pour la partie spécifiée 1 pour Janvier, 2 pour Fevrier etc.


Vous êtes SQL pourrait être aidé avec les fonctions COALESCE() et ISNULL(). Ceci est le même que votre première sélectionnez:

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 

Je pense qu'il ya un bug dans votre sélection, je crois que votre dernière ligne doit être le suivant:

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

Mais j'aurais pour tester cela pour être sûr.


Ajout dans rollups est difficile à faire - en général cela se fait à l'extérieur du SQL dans le contrôle ou tout affiche les résultats. Vous pourriez faire quelque chose comme ceci (exemple artificiel):

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 

ou vous ne pourriez pas avoir la colonne totale « extra » et le mettre dans la colonne quantité.

Questions connexes