Voorwaardelijke groep door in sql-server?

ik heb deze eenvoudige vraag:

SELECT YEAR(P.DateCreated)
      ,MONTH(P.DateCreated)
      ,COUNT(*) AS cnt
FROM   tbl1,
       tbl2....
GROUP BY
         MONTH(P.DateCreated)
        ,YEAR(P.DateCreated)

dit zal uitzenden:

enter image description here

nu heb ik dezelfde query nodig, maar met groupby alleen per jaar:

zo:

SELECT YEAR(P.DateCreated)

      ,COUNT(*) AS cnt
FROM   tbl1,
       tbl2....
GROUP BY
         YEAR(P.DateCreated)

i dont wil 2 queries maken.

is er een manier waarop ik hier conitional group by kan doen?

Ik kan doen met een wordt vervangen door een , maar i kan niet doen de ene wordt vervangen door twee ...

GROUP BY
     CASE WHEN @timeMode='y' THEN YEAR(P.DateCreated)
          WHEN @timeMode='m' THEN MONTH(P.DateCreated), YEAR(P.DateCreated) end

enter image description here

alle hulp ?

7

2 antwoord

Je zou beter af zijn met twee afzonderlijke vragen, maar kan het doen

GROUP BY YEAR(P.DateCreated),
       CASE 
          WHEN @timeMode='m' THEN MONTH(P.DateCreated) end

As WHEN @timeMode <> 'm' the second GROUP BY expression will be NULL for all rows and not affect the result.

15
toegevoegd
als ik @ timeMode = 'y' toevoeg zodat de vraag , aan het einde .... fout zal hebben?
toegevoegd de auteur Royi Namir, de bron
dus ik moet beginnen met kleinste groep voor eenheid, en dan uitbreiden per geval .... riught?
toegevoegd de auteur Royi Namir, de bron
is group by myColumn, null, null geldig?
toegevoegd de auteur Royi Namir, de bron
bedankt man maar toch heb ik een vraag: je kunt consts in groep niet gebruiken (zoals je zei), maar aan de andere kant, hoe zal deze GROEP PER JAAR (P.DateCreated), CASE WHEN @ timeMode = 'm' DAN kan MAAND (P.DateCreated) end werken? if @timeMode <> 'm' dus wat is de waarde daar? het is niet nul omdat group by cant nul const binnenkant van het kan ... kunt u alsjeblieft uitleggen?
toegevoegd de auteur Royi Namir, de bron
bedankt. :) bedankt. :)bedankt. :)
toegevoegd de auteur Royi Namir, de bron
Ik weet niet zeker wat je vraagt. CASE kan slechts één expressie retourneren. Dit geeft antwoord op de vraag die je eigenlijk hebt gesteld.
toegevoegd de auteur Martin Smith, de bron
@RoyiNamir - De volgorde van de expressies in de GROEP VOOR maakt geen enkel verschil. Het belangrijkste is dat als je geen GROUP BY een expressie wilt, zorg er dan voor dat het een constante waarde retourneert. Met IIRC SQL Server kunt u een dergelijke constante in de uitdrukking GROUP BY niet gebruiken. Ik heb SSMS nog niet open om te testen op dit moment
toegevoegd de auteur Martin Smith, de bron
@RoyiNamir - Het is NULL . SQL Server voorkomt niet dat u groepeert op een expressie die mogelijk NULL retourneert. Het verbiedt alleen uitdrukkingen die niet verwijzen naar gegroepeerd op tabel (en). GROUP BY CASE WANNEER 1 = 0 DAN is myColumn ELSE NULL END geldig, ook al kan het alleen ooit evalueren naar NULL .
toegevoegd de auteur Martin Smith, de bron

U kunt een over -clausule gebruiken om zowel de telling per jaar als de telling per maand in één query terug te zetten:

SELECT  distinct YEAR(P.DateCreated) as Year
,       MONTH(P.DateCreated) as Month
,       COUNT(*) over (partition by YEAR(P.DateCreated), MONTH(P.DateCreated)) 
            as MonthCount
,       COUNT(*) over (partition by YEAR(P.DateCreated)) as YearCount
FROM   YourTable P

Live voorbeeld op SQL Fiddle.

5
toegevoegd
ik zie niet hoe het helpt ... :) kunt u alstublieft uitwerken
toegevoegd de auteur Royi Namir, de bron
Het zou beide resultaten teruggeven. Als u de vraag tussen twee modi wilt schakelen, bekijkt u @ MartinSmith's antwoord!
toegevoegd de auteur Andomar, de bron