No último post começamos a conversar sobre o comando SELECT.
Tenho certeza que você já conhece alguns aspectos importantes do comando, mas chegamos no momento de dar um passo além!!!
FROM
FROM é a primeira claúsula avaliada logicamente pela engine do banco de dados, é onde você indica as tabelas/ views ou functions que farão parte da query. Neste momento da consulta são aplicados os joins.
As tabelas/ views ou functions tem seu nome representado por duas partes, o schema e a tabela.
SCHEMAs são coleções de objetos dentro do SQL Server. A vantagem de usar um schema é a possibilidade de criar grupos e usuários de forma mais fácil, por exemplo, posso colocar todas as tabelas de RH no schema RH e dar permissão de leitura neste schema só aos funcionários do RH. A outra vantagem é a possibilidade de agrupar fisicamente os objetos que fazem parte de um schema para administração de backups.
O schema não é obrigatório, mas eu aconselho a usar sempre.
Outro item opcional é o ALIAS, que é um apelido para uma tabela ou coluna. O Alias pode ser atribuído de duas formas diferentes:
* <nome da tabela> <Alias>
* <nome da tabela> AS <Alias>
As duas formas estão certas, mas eu particularmente eu sou fã da segunda, e aconselho você a usar nomes menores e significativos no Alias, para facilitar a escrita e o entendimento das queries.
--Usar o ALIAS e o nome da tabela SELECT SalesOrderHeader.SalesOrderID, SOH.Comment FROM Sales.SalesOrderHeader AS SOH
SELECT
Tem dois papéis principais:
1- É onde definimos o retorno da nossa query. Nela são avaliadas as expressões que definem as colunas da query resultante, atribuindo a eles um alias se for necessário;
2- Usar a clausula DISTINCT para eliminar os registros duplicados do retorno da query
Quando queremos que a query retorne todas as colunas de uma tabela, podemos usar o “*” , ao invés de explicitamente declarar os nomes das colunas. NÃO É UMA BOA PRÁTICA FAZER ISSO (ok… em testes é aceitável, em produção não!).
Assim como na clausula FROM podemos definir alias para as expressões que fazem parte do retorno da query.
A forma de declarar o alias é igual (a forma usada na claúsula FROM) e eu prefiro usar a forma mais completa. Quanto mais fácil de ler a query, menos complicadas são as manutenções.
Preste muita atenção com as virgulas no SELECT! Se você esquecer de colocar uma virgula entre o nome de duas colunas, o SQL Server vai interpretar que a segunda coluna é um ALIAS. Entende o perigo?
--Esquecer a vírgula entre as colunas SELECT SalesOrderID Comment FROM Sales.SalesOrderHeader
Um uso importante do ALIAS é nomear expressões, porque sem o alias elas resultam em uma coluna sem nome.
--Retorno de uma expressão sem ALIAS SELECT OrderQty *10 FROM Sales.SalesOrderDetail
--Retorno de uma expressão com ALIAS SELECT OrderQty *10 AS EXPRESSAO FROM Sales.SalesOrderDetail
Uma diferença importante entre o T-SQL e o SQL padrão, é que no padrão não existe SELECT sem FROM, e no T-SQL existe!
--SELECT SEM FROM SELECT 'SQLSERVER' as Coluna
Podemos delimitar o nome das colunas com “” ou com []. Quando o nome segue o padrão definido delimitar o nome da coluna é opcional, mas se uma das regras abaixo não for respeitada é necessário delimitar o nome:
- O primeiro caracter deve ser ser uma letra definida no padrão Unicode 3.2, ou o “_”, ou “@” ou “#”. Os caracteres seguintes podem ser letras ou números.
- Não podem ter espaços e nem palavras reservadas para o T-SQL
Filtrar dados com predicados
Vamos começar lembrando que NULL não é um valor (embora eu mesma sempre que não me policio cometo a gafe de falar valor nulo…Desculpem mas é um hábito ruim que eu não perco)
Se você tentar fazer uma query e na clausula WHERE colocar a seguinte condição <nome da coluna> = NULL a sua consulta nunca retornará nenhum resultado., pelo simples fato de NULL não ser um valor, e por isso é impossível para o SQL Server fazer esta comparação. Mas se quisermos retornar na query as colunas que são nulas devemos usar o seguinte predicado: <nome da coluna> IS NULL
--Usando NULL de forma INCORRETA na comparação SELECT OrderQty FROM Sales.SalesOrderDetail WHERE UnitPrice = NULL
--Usando NULL de forma correta na comparação SELECT OrderQty FROM Sales.SalesOrderDetail WHERE UnitPrice is NULL
Se quisermos filtrar o retorno da nossa query, com as colunas que não são nulas podemos usar o predicado <nome da coluna> IS NOT NULL.
--Selecionar OederQty da tabela SalesOrderDetail, onde a coluna UnitPrice não seja Null SELECT OrderQty FROM Sales.SalesOrderDetail WHERE UnitPrice is not NULL
Combinando Predicados
No mundo real, as nossas consultas podem ter vários predicados… que são várias condições. Ou seja o retorno de nossa consulta serão as linhas que obedecerem um conjunto de condições. Combinamos as condições com os operadores lógicos AND, OR e NOT
Use o NOT para inverter uma condição, por exemplo…
SELECT NomeFuncionario FROM Funcionario WHERE NOT(situação = ‘ativo’)
Traduzindo o comando, selecione o nome do funcionário, da tabela de funcionários onde a situação não seja igual a ‘ativo’
Cuidado com a precedência na hora de montar suas condições… NOT precede o AND, que precede o OR
Assim como na matemática use parênteses para que as condições sejam executadas na ordem correta.
Predicados são avaliados da esquerda para a direita, logicamente. Quando falamos da execução física o plano de otimização é quem decide qual condição será avaliada primeiro.
Filtrando caracteres
Antes de falar sobre este tipo de filtro é legal falar de conversões implícitas… Isso ocorre quando comparamos dados de tipos diferentes, mas que são compatíveis ou que comparamos o resultado de uma expressão. Internamente o SQL converte os dados para depois fazer a consulta. Por exemplo… Existe o tipo de dados NVARCHAR (strings do tipo UNICODE com tamanho variável) e existe o tipo de dados VARCHAR. Quando usamos comparações com o NVARCHAR sempre colocamos um N antes da string por exemplo:
WHERE lastname = N’Monteiro’
Isso indica para o SQL Server que a palavra ‘Monteiro’ é um texto UNICODE e a query será executada da melhor maneira. Entretanto se escrevermos a query da seguinte maneira:
WHERE lastname = ’Monteiro’
E a coluna lastname é do tipo NVARCHAR, internamente o SQL Server converterá a string ‘Monteiro’ para UNICODE para depois verificar a condição. Entendem que as conversões utilizam recursos desnecessariamente?
Temos o predicado LIKE para consultar padrões de string, devemos usá-lo na clausula WHERE e ele tem o seguinte padrão:
<coluna> LIKE <padrão>
Veja a documentação oficial com as possibilidades de uso do LIKE.
Filtrando datas e horas
Cuidado com o filtro de datas!!! Porque o formato usado depende do idioma da linguagem associado ao login. Normalmente os DBAs mais ajuizados usam o padrão americano (opinião da Dani…) existe também a propriedade DATEFORMAT que o DBA atribui para o login (só para causar mais confusão, é possível criar um login com idioma padrão americano e o formato de data japonês).
E como sair desta sinuca de bico? Uma solução é usar um formato neutro como “20170813” que sempre será entendido pelo SQL Server como ano, mês e dia, independentemente do idioma. O formato “2017–08–13” é considerado neutro para os tipos DATE, DATETIME2 e DATETIMEOFFSET, mas não é considerado neutro para os tipo DATETIME E SMALLDATETIME, sendo assim tenha cuidado!
Podemos usar a função CONVERT para converter as datas para um determinado padrão
- A função CONVERT é muito útil, não só para converter datas deem uma olhada na documentação.
- Existe também a função CAST que tem o mesmo objetivo, mas é padrão ANSI
https://msdn.microsoft.com/pt-br/library/ms187928(v=sql.120).aspx - Quando usamos filtros com colunas do tipo DATETIME é necessário tomar cuidado com a precisão e com os arredondamentos, use intervalos fechados e na mesma precisão dos dados
Dica
Teste os comandos apresentados neste post. Eles estão no gitHub. Veja se há diferenças nos comandos executados no SQL Server 2017 e no SQL Azure. Depois me conta os resultados!
Conclusão
Null não é valor… Tome cuidado com os ALIAS… Cuidado com o padrão de datas… E me prometa que você irá treinar e treinar… Assim seus comandos serão cada vez mais profissionais e seus aplicativos cada vez melhores!