none
Ottenere lista anni compresi tra due DateTime (da DateTime a Varchar) RRS feed

  • Domanda

  • Ciao a tutti,
    avendo due variabili DateTime, come posso crearmi una variabile VARCHAR che mi contenga la lista degli anni compresi tra queste due date separati da virgola?

    Ad esempio, se ho:

    DECLARE @DataDa DATETIME, @DataA DATETIME, @Anni VARCHAR(300)
    SET @DataDa = '2010-10-10 00:00:00'
    SET @DataA = '2012-12-31 00:00:00'

    dovrei ottenere nella variabile @Anni '2010,2011,2012'

    Ovviamente se coprono solo un anno, dovrei avere solo l'anno in questione.

    E' possibile farlo in T-SQL?

    Grazie

    Luigi

    martedì 1 marzo 2011 13:12

Risposte

  • Puoi provare in questo modo:


    DECLARE
        @DataDa DATETIME,
        @DataA DATETIME, @Anni VARCHAR(300),
        @ListaAnni varchar(2000),
        @i int
       
    SET @DataDa = '2010-10-10 00:00:00'
    SET @DataA = '2012-12-31 00:00:00'
    SET @ListaAnni = ''
    SET @i = 0

    WHILE @i <= DATEDIFF(year, @DataDa, @DataA)
    BEGIN
        SET @ListaAnni = @ListaAnni + CASE LEN(@ListaAnni) WHEN 0 THEN '' ELSE ',' END + CAST(YEAR(@DataDa) + @i AS char(4))
        SET @i = @i + 1
    END

    SELECT @ListaAnni


    Danilo Dominici MCP MCDBA MCITP MCSE MCAD
    • Contrassegnato come risposta Ciupaz mercoledì 2 marzo 2011 09:15
    martedì 1 marzo 2011 14:10
  • Ciao a tutti,
    avendo due variabili DateTime, come posso crearmi una variabile VARCHAR che mi contenga la lista degli anni compresi tra queste due date separati da virgola?

    Ciao Luigi,

    Ti propongo una soluzione alternativa rispetto a quella proposta da Danilo basata su una CTE ricorsiva e sulla clausola FOR XML PATH:

    USE tempdb;
    GO
    
    CREATE FUNCTION dbo.udf_GetYears(
    @From date,
    @To date
    )
    RETURNS TABLE
    RETURN(
      WITH CTE_Years AS
      (
        SELECT YEAR(@From) AS [Year]
        UNION ALL
        SELECT [Year] + 1
        FROM CTE_Years
        WHERE [Year] < YEAR(@To)
      )
      SELECT *
      FROM CTE_Years
    );
    GO
    
    DECLARE @Years varchar(20);
    
    SELECT @Years = STUFF(
       (
        SELECT ', ' + CAST([Year] AS char(4)) AS [text()]
        FROM dbo.udf_GetYears('20101010', '20121231')
        FOR XML PATH('')
       ), 1, 2, '');
    
    PRINT @Years;
    
    /* Output
    
    2010, 2011, 2012
    
    */
    
    DROP FUNCTION dbo.udf_GetYears;
    
    Ciao!
    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.microsoft.com/Forums/it-IT/sqlserverit
    • Contrassegnato come risposta Ciupaz mercoledì 2 marzo 2011 09:15
    mercoledì 2 marzo 2011 09:01
    Moderatore

Tutte le risposte

  • Puoi provare in questo modo:


    DECLARE
        @DataDa DATETIME,
        @DataA DATETIME, @Anni VARCHAR(300),
        @ListaAnni varchar(2000),
        @i int
       
    SET @DataDa = '2010-10-10 00:00:00'
    SET @DataA = '2012-12-31 00:00:00'
    SET @ListaAnni = ''
    SET @i = 0

    WHILE @i <= DATEDIFF(year, @DataDa, @DataA)
    BEGIN
        SET @ListaAnni = @ListaAnni + CASE LEN(@ListaAnni) WHEN 0 THEN '' ELSE ',' END + CAST(YEAR(@DataDa) + @i AS char(4))
        SET @i = @i + 1
    END

    SELECT @ListaAnni


    Danilo Dominici MCP MCDBA MCITP MCSE MCAD
    • Contrassegnato come risposta Ciupaz mercoledì 2 marzo 2011 09:15
    martedì 1 marzo 2011 14:10
  • Ciao a tutti,
    avendo due variabili DateTime, come posso crearmi una variabile VARCHAR che mi contenga la lista degli anni compresi tra queste due date separati da virgola?

    Ciao Luigi,

    Ti propongo una soluzione alternativa rispetto a quella proposta da Danilo basata su una CTE ricorsiva e sulla clausola FOR XML PATH:

    USE tempdb;
    GO
    
    CREATE FUNCTION dbo.udf_GetYears(
    @From date,
    @To date
    )
    RETURNS TABLE
    RETURN(
      WITH CTE_Years AS
      (
        SELECT YEAR(@From) AS [Year]
        UNION ALL
        SELECT [Year] + 1
        FROM CTE_Years
        WHERE [Year] < YEAR(@To)
      )
      SELECT *
      FROM CTE_Years
    );
    GO
    
    DECLARE @Years varchar(20);
    
    SELECT @Years = STUFF(
       (
        SELECT ', ' + CAST([Year] AS char(4)) AS [text()]
        FROM dbo.udf_GetYears('20101010', '20121231')
        FOR XML PATH('')
       ), 1, 2, '');
    
    PRINT @Years;
    
    /* Output
    
    2010, 2011, 2012
    
    */
    
    DROP FUNCTION dbo.udf_GetYears;
    
    Ciao!
    Lorenzo Benaglia
    Microsoft MVP - SQL Server
    http://blogs.dotnethell.it/lorenzo
    http://social.microsoft.com/Forums/it-IT/sqlserverit
    • Contrassegnato come risposta Ciupaz mercoledì 2 marzo 2011 09:15
    mercoledì 2 marzo 2011 09:01
    Moderatore
  • Grazie a entrambi. Sono due soluzioni che mi devo studiare un attimo, soprattutto la seconda.

    Luigi

    mercoledì 2 marzo 2011 09:14