Trabalhando com datas – Lista de meses e dias da semana

Pessoal, no último post relacionei funções para trabalhar com campos do tipo data, acabei recebendo um bom feedback e algumas perguntas sobre como relacionar todos os meses ou dias da semana por meio de query. Para responder estas perguntas, relacionei formas de gerar listas com os meses e dias da semana por meio de CTE.

Nestas duas primeiras queries, faço uso de um CTE recursivo básico, com as funções DATENAME e DATEADD e a instrução SET LANGUAGE para definir o idioma ‘Brasileiro’. Estas queries são bem mais simples e tornam mais fácil trazer novos campos. 

Tips:
1: Os campos de data quando somados a tipos inteiros, adicionam o valor dos inteiros em dias.
2: A função DATEADD simplifica a adição de outros quantitativos como meses, horas e anos.
3: O inteiro ‘0’ (zero) quando convertido para data se torna ‘1900-01-01 00:00:00.000’, uma segunda-feira.
4: O inteiro ‘-1’ quando convertido para data se torna ‘1899-12-31 00:00:00.000’, um domingo.

Gerando uma lista de meses:

SET LANGUAGE 'Brazilian'
;WITH Meses AS
(
  SELECT 1 AS IdMes, DATENAME(MONTH, 0) AS NomeMes
  UNION ALL
  SELECT IdMes + 1, DATENAME(MONTH, DATEADD(MONTH, IdMes, 0))
  FROM Meses
  WHERE IdMes < 12
)
SELECT * FROM Meses

Gerando uma lista de dias da semana começando pelo domingo:

SET LANGUAGE 'Brazilian'
;WITH DiaSemana AS
(
  SELECT 1 AS idDSe, DATENAME(WEEKDAY, -1) AS nomeDSe
  UNION ALL
  SELECT idDSe + 1, DATENAME(WEEKDAY, idDSe -1)
  FROM DiaSemana
  WHERE idDSe < 7
)
SELECT idDSe, nomeDSe FROM DiaSemana

Ou pela Segunda-Feira:

SET LANGUAGE 'Brazilian'
;WITH DiaSemana AS
(
  SELECT 1 AS idDSe, DATENAME(WEEKDAY, 0) AS nomeDSe
  UNION ALL
  SELECT idDSe + 1, DATENAME(WEEKDAY, idDSe)
  FROM DiaSemana
  WHERE idDSe < 7
)
SELECT idDSe, nomeDSe FROM DiaSemana

Nas duas próximas queries, avanço um pouco a complexidade das CTEs, utilizando a view syslanguage e uma CTE de Split que modifiquei do site do Zavaschi. Elas realmente se diferenciam pelo campo utilizado da syslanguages facilitando alterações neste sentido.

Gerando uma lista dos meses:

DECLARE @Texto VARCHAR(8000),
        @Delimitador CHAR
SET @Texto = (SELECT months FROM sys.syslanguages WHERE alias = 'Brazilian')
SET @Delimitador = ','
;WITH _SPLIT(ID, _INDEX, _LENGTH) AS
(
  SELECT
    1,
    1,
    CHARINDEX(@Delimitador, @Texto + @Delimitador)
UNION ALL
  SELECT
    ID + 1,
    _LENGTH + 1,
    CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1)
  FROM _SPLIT
  WHERE CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1) <> 0
)
, Meses (idMes, nomeMes) AS
(
  SELECT
    ID,
    SUBSTRING(@Texto, _INDEX, _LENGTH - _INDEX)
  FROM _SPLIT
)
SELECT idMes, nomeMes FROM Meses

Gerando uma lista de dias da semana:

DECLARE @Texto VARCHAR(8000),
        @Delimitador CHAR
SET @Texto = (SELECT days FROM sys.syslanguages WHERE alias = 'Brazilian')
SET @Delimitador = ','
;WITH _SPLIT(ID, _INDEX, _LENGTH) AS
(
  SELECT
    1,
    1,
    CHARINDEX(@Delimitador, @Texto + @Delimitador)
UNION ALL
  SELECT
    ID + 1,
    _LENGTH + 1,
    CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1)
  FROM _SPLIT
  WHERE CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1) <> 0
)
, DiaSemana (idDSe, nomeDSe) AS
(
  SELECT
    ID,
    SUBSTRING(@Texto, _INDEX, _LENGTH - _INDEX)
  FROM _SPLIT
)
SELECT idDSe, nomeDSe FROM DiaSemana

Eu espero que elas respondam as necessidades que venham a aparecer!

Não se esqueçam de comentar!

Anúncios

12 pensamentos sobre “Trabalhando com datas – Lista de meses e dias da semana

  1. Pingback: WHILE vs CTE – Popular tabela de testes « SQL from Hell !!!

  2. Pingback: CTE – Introdução « Sql From Hell.com

  3. Pingback: FUNÇÕES: Listas de valores numéricos « Sql From Hell.com

  4. Pingback: Trabalhando com datas – Scripts para trabalhar com os dias de um mês « SQL From Hell.com

  5. Muito interessante o post.. parabens

    Gostaria de saber tambem se ha alguma queries para listar os dias dos meses, não informar se o mes tem
    30 ou 31, e sim listar os dias atraves de uma data ex:(getdate()), 1,2,3,4,5,6..31

    Grande abraço

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s