SQL vs DAX - Trabalhando com strings
Um comparativo de como trabalhar com strings no SQL e no DAX
Neste artigo vamos ver algumas operações de manipulação de strings no SQL e no DAX.
Esta é a continuação de uma série de artigos comparando o SQL com o DAX. Se você perdeu os artigos anteriores, os links são estes:
SQL vs DAX - Operações básicas
SQL vs DAX - Filtrando registros
Primeiro vamos criar os dados que vamos usar como exemplo
SQL
CREATE TABLE Clientes (
[Nome] [varchar](50) NULL,
[Email] [nvarchar](50) NULL,
[DataCadastro] [date] NULL
)
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('João', 'joao@teste.com.br','2021-01-01');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Lucas', 'lucas@teste.com.br','2021-01-17');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Matheus', 'matheus@teste.com.br','2021-02-12');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Thiago', 'thiago@teste2.com.br','2021-02-20');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Madalena', 'madalena@teste.com.br','2021-03-02');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Pedro', 'pedro@teste.com.br','2021-03-11');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('David', 'david@teste2.com.br','2021-03-29');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Salomão', 'salomao@teste.com.br','2021-03-30');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Zedebeu', 'zebedeu@teste.com.br','2021-04-06');
INSERT INTO Clientes (Nome, Email, DataCadastro) VALUES ('Josue', 'josue@teste2.com.br','2021-06-05');
DAX
Clientes =
DATATABLE(
"Nome", STRING,
"Email", STRING,
"DataCadastro", DATETIME,
{
{'João', 'joao@teste.com.br','2021-01-01'},
{'Lucas', 'lucas@teste.com.br','2021-01-17'},
{'Matheus', 'matheus@teste.com.br','2021-02-12'},
{'Thiago', 'thiago@teste2.com.br','2021-02-20'},
{'Madalena', 'madalena@teste.com.br','2021-03-02'},
{'Pedro', 'pedro@teste.com.br','2021-03-11'},
{'David', 'david@teste2.com.br','2021-03-29'},
{'Salomão', 'salomao@teste.com.br','2021-03-30'},
{'Zedebeu', 'zebedeu@teste.com.br','2021-04-06'},
{'Josue', 'josue@teste2.com.br','2021-06-05'}
}
)
Neste exemplo vamos ver como podemos separar o nome do usuário e o nome do domínio dos dados informados no campo e-mail.
Se faz necessário primeiro localizar a posição do "@" no campo e-mail. O que estiver a esquerda do "@" é o nome do usuário e o que estiver a direita é o domínio. Para localizar a posição do "@" faremos da seguinte forma:
SQL
SELECT Nome, Email, CHARINDEX('@', Email) as Posicao, LEN(Email) as TamanhoEmail FROM Clientes
DAX
EVALUATE
SELECTCOLUMNS(
'Clientes',
"Nome",[Nome],
"Email", [Email],
"Posicao", FIND("@", [Email]),
"TamanhoEmail", LEN([Email])
)
A função SELECTCOLUMNS permite escolher colunas da origem de dados informada como primeiro parâmetro. Perceba que criamos dois campos calculados, o primeiro se chama Posicao é utiliza a função FIND. FIND recebe dois parâmetros, o primeiro é a string que desejamos localizar e o segundo é o campo que será pesquisado. Seu retorno é um número que representa a primeira posição onde a string informada foi localizada.
A segunda coluna calculada se chama TamanhoEmail e usa a função LEN para retornar o tamanho do campo Email.
Agora que temos a posição do "@" podemos fazer a primeira parte que seria separar o nome de usuário do e-mail.
SQL
SELECT Nome, Email, CHARINDEX('@', Email) as Posicao, LEN(Email) as TamanhoEmail,
SUBSTRING(Email,1, CHARINDEX('@', Email)-1) as Usuario
FROM Clientes
DAX
EVALUATE
SELECTCOLUMNS(
'Clientes',
"Nome",[Nome],
"Email", [Email],
"Posicao", FIND("@", [Email]),
"TamanhoEmail", LEN([Email]),
"Usuario", MID([Email],1,FIND("@", [Email])-1)
)
Em relação a consulta anterior, acrescentamos mais um campo calculado que é o campo Usuario. Quando desejamos selecionar uma parte de uma string utilizamos a função MID. A função MID recebe 3 parâmetros, o primeiro é a coluna que vai ser pesquisada, o segundo é a posição inicial que desejamos retornar a string e o último é a posição final. Perceba que como último parâmetro utilizamos a função FIND usada no exemplo anterior, subtraindo 1 do seu resultado. Fizemos isso porque não desejamos que o "@" seja retornado no resultado.
Agora vamos para a última parte, que é separar o nome de domínio do Email.
SQL
SELECT Nome, Email, CHARINDEX('@', Email) as Posicao, LEN(Email) as TamanhoEmail,
SUBSTRING(Email,1, CHARINDEX('@', Email)-1) as Usuario,
SUBSTRING(Email,CHARINDEX('@', Email)+1, LEN(Email)-CHARINDEX('@', Email)) as Dominio
FROM Clientes
DAX
EVALUATE
SELECTCOLUMNS(
'Clientes',
"Nome",[Nome],
"Email", [Email],
"Posicao", FIND("@", [Email]),
"TamanhoEmail", LEN([Email]),
"Usuario", MID([Email],1,FIND("@", [Email])-1),
"Dominio", MID([Email],FIND("@", [Email])+1,LEN([Email])-FIND("@", [Email]))
)
Perceba que para criar a coluna Dominio também usamos o MID. A diferença em relação ao exemplo anterior é o terceiro parâmetro desta função. Como posição final fizemos a subtração do tamanho total do campo (LEN) menos a posição onde se encontra o "@" (FIND)
Se você quiser padronizar os nomes em maiúsculo ou minúsculo pode fazer da mesma forma como se faz no SQL. No SQL usamos as funções UPPER para converter em maiúsculo e LOWER para converter em minúsculo. No DAX também é assim
SQL
SELECT UPPER(Nome) as Nome, Email FROM Clientes
SELECT LOWER(Nome) as Nome, Email FROM Clientes
DAX
EVALUATE
SELECTCOLUMNS(
'Clientes',
"Nome",UPPER([Nome]),
"Email", [Email]
)
EVALUATE
SELECTCOLUMNS(
'Clientes',
"Nome",LOWER([Nome]),
"Email", [Email]
)
Vamos encerrar este artigo vendo como concatenar strings.
No SQL utilizamos a função CONCAT
SELECT Nome, Email, CONCAT(Nome, ' cadastrado a ', DATEDIFF(DAY, DataCadastro, GETDATE()), ' dias') as mensagem FROM Clientes
A função CONCAT aceita vários parâmetros. O campo mensagem vai exibir o nome e a quantidade de dias em que o cliente se encontra cadastrado.
Já no DAX se utiliza a função CONCATENATE
EVALUATE
SELECTCOLUMNS(
'Clientes',
"Nome",[Nome],
"Email", [Email],
"DataCadastro", [DataCadastro],
"DiasCadastrado", DATEDIFF([DataCadastro],TODAY(),DAY),
"MesesCadastrado", DATEDIFF([DataCadastro],TODAY(),MONTH),
"Mensagem", CONCATENATE([Nome], " cadastrado a " & DATEDIFF([DataCadastro],TODAY(),DAY) & " dias")
)
Ao contrário do seu similar do SQL, CONCATENATE apenas aceita dois parâmetros. Para poder unir mais conteudos, tivemos que utilizar o operador &