Sie sind auf Seite 1von 138

1

TRANSACT - SQL

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

O que Datatype.................................................................................................................................... 11 DML SELECT, INSERT, UPDATE e DELETE ............................................................................................... 16 Utilizao do comando SELECT ........................................................................................................... 16 Exibindo os dados de todas as colunas da tabela Funcionario ......................................................... 18 Utilizao do comando INSERT ........................................................................................................... 32 Utilizao do comando UPDATE ......................................................................................................... 42 Utilizao do comando DELETE ........................................................................................................... 45 A clusula WHERE ................................................................................................................................... 47 Critrio ............................................................................................................................................ 58 Resumo ............................................................................................................................................ 58 IN / NOT IN ....................................................................................................................................... 58 BETWEEN /NOT BETWEEN ............................................................................................................. 58 LIKE / NOT LIKE / SCAPE ................................................................................................................ 58 IS NULL / IS NOT NULL .................................................................................................................... 58 A clusula ORDER BY............................................................................................................................... 60 Ordenando pela posio da coluna ..................................................................................................... 62 Argumentos ....................................................................................................................................... 63 A clusula TOP ........................................................................................................................................ 65 TOP n ................................................................................................................................................. 65 TOP n PERCENT .................................................................................................................................. 66 TOP n , TOP n PERCENT WITH TIES com ORDER BY.............................................................................. 67 Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

TOP n com UPDATE e DELETE ............................................................................................................. 68 A clusula OUTPUT ................................................................................................................................. 69 UPDATE com OUTPUT ........................................................................................................................ 71 DELETE com OUTPUT ......................................................................................................................... 72 Group By ................................................................................................................................................ 73 Funes de Totalizao ...................................................................................................................... 75 Utilizando Group By ........................................................................................................................... 77 HAVING.............................................................................................................................................. 78 ROLLUP()............................................................................................................................................ 78 CUBE() ............................................................................................................................................... 79 GROUPING SET() ................................................................................................................................ 79 CASE ....................................................................................................................................................... 80 Case com SELECT................................................................................................................................ 82 Case com ORDER BY ........................................................................................................................... 84 Case com UPDATE .............................................................................................................................. 85 Case com HAVING .............................................................................................................................. 86 A clusula UNION ................................................................................................................................... 87 UNION ............................................................................................................................................... 89 UNION ALL ......................................................................................................................................... 92 GROUPING SETS()............................................................................................................................... 93 INTERSECT e EXCEPT .......................................................................................................................... 94 Joins Transformando dados em informao ......................................................................................... 97 Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

INNER JOIN ...................................................................................................................................... 100 LEFT JOIN ......................................................................................................................................... 107 RIGHT JOIN ...................................................................................................................................... 110 FULL JOIN......................................................................................................................................... 113 CROSS JOIN ...................................................................................................................................... 114 Join com mais de duas tabelas.......................................................................................................... 116 Evitando Ambiguidade ..................................................................................................................... 119 UPDATE COM JOIN ........................................................................................................................... 120 DELETE COM JOIN ............................................................................................................................ 121 Joins entre tabelas que possuem Chaves Compostas ........................................................................ 122 SUBQUERY............................................................................................................................................ 124 Subquery Introduzida com Operador de Comparao ....................................................................... 127 Subquery Introduzida com IN ou NOT IN .......................................................................................... 129 Subquery Introduzida com EXISTS e NOT EXISTS ............................................................................... 131 Substituindo Subqueries................................................................................................................... 133 Subqueries Aninhadas ...................................................................................................................... 136 UPDATE COM SUBQUERY ................................................................................................................. 138 DELETE COM SUBQUERY .................................................................................................................. 138

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

INTRODUO
A utilizao de databases para o armazenamentos de dados, surge nos anos 60, e o primeiro modelo a ser utilizado foi o Hierrquico, seguidos pelos modelos Rede, Relacionais, Dedutivo e o Objeto.

A liguaguagem SQL surge com a criao do Modelo Relacional proposta pelo Dr. Edgard Frank Codd j nos anos 70.

O QUE SIGNIFICA A SIGLA SQL


SQL o nome que foi atribudo linguagem declarativa utilizada no tratamento de dados armazenados no formato relacional.

A sigla SQL quer dizer Structured Query Language, ou seja, Linguagem Estruturada de Pesquisa e, foi idealizada e desenvolvida nos laboratrios da IBM USA.

Quando criada recebeu outro nome, SEQUEL, que significava Structured English Query Language Linguagem Estruturada em Ingls para Pesquisa.

A linguagem SEQUEL foi utilizada para demonstrar a viabilidade do modelo de armazenamento relacional idealizado pelo Dr. Cood.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

Com o passar do tempo a liguagem teve seu nome alterado para SQL, mas l nos Estados Unidos seu nome ainda pronunciado como Sequel.

Tambm com o passar do tempo, com sua aceitao e utilizao pelos profissionais de banco banco de dados, a liguagem SQL acabou se tornando um padro. Na realidade, surgiram vrios dialtos desta liguagem e houve a necessidade de padronizar a sua utilizao.

Sendo assim, em 1986 ela foi padronizada pelo instituto ANSI e em 1987 pelo ISO.

A padronizao da SQL foi revista em 1992 e, justamente por isso passa a ser chamada de SQL-92 ou SQL2

Em 1999 houve outra reviso onde a linguagem passa a se chamar SQL:1999 ou SQL3.

SQL o nome que foi atribudo linguagem declarativa utilizada no tratamento de dados armazenados no formato relacional.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

Na padronizao, os comandos da liguagem SQL foram agrupados de acordo com suas funes como segue:

1 DCL Data Control Language GRANT REVOKE

2 DDL Data Definition Language CREATE ALTER DROP

3 DML Data Manipulation Language SELECT INSERT UPDATE DELETE

Apesar da padronizao, ainda h uma certa diferena na sintaxe da SQL utilizada pelas empresas que desenvolvem os gerenciadores de banco de dados, e aqui neste tutorial, utilizamos a sintaxe da Microsoft e vamos comear pelas demonstraes dos comandos da DML.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

DML DATA MANIPULATION LUANGUAGE


Na traduo, DML significa Linguagem de Manipulao da Dados, como foi dito anteriormente, e ela abrange os comandos SELECT, INSERT, UPDATE E DELETE, ou seja, comandos para leitura, incluso, alterao e excluso de dados.

Neste material, empregando a sintaxe Microsoft, exibimos a utilizao detalhada da DML.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

DATABASE, TABELAS E DATATYPES


O QUE UM DATABASE
No SQL Server, um database o nome que se d para um conjunto de arquivos de dados e de transaes.

Todo database do SQL Server tem pelo menos dois arquivos, uma para armazenar dados de tabelas e de indices e o outro para armazenar as transaes (comandos que inserem, alteram e excluem os dados de uma tabela).

Esses databases podero, se necessrio, ter mais de um arquivo de dados e/ou mais de um arquivo de transaes.

Como o objetivo deste tutorial exibir a forma de utilizao dos comandos DML, vamos aqui criar um database com todas as opes definidas como default e com os arquivos de dados e de transaes que o prprio SQL Server define durante a execuo do comando CREATE DATABASE.

Para tanto siga as instrues abaixo:

Clique no menu Start / Programs / Microsoft SQL Server 2008/ SQL Server Management Studio.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

10

Conecte-se no SQL Server, apenas clicando no boto Connect.

Em seguida, na barra de menu, escolha a opo New Query.

Surge para voc uma rea onde os comandos so digitados e executados.

Escreva o comando abaixo para criar um database chamado 50minutos, com todas as opes de armazenamento e dimensionamento definidas como default:

CREATE DATABASE [50minutos]

Pressione a tecla F5 para executar o comando.

Pronto, voc j tem um database criado!

Em seguida, escreva o comando abaixo para acessar o database 50minutos, selecione apenas esta linha e tecle F5 para execut-lo.

USE [50minutos]

Observe no alto e do lado esquerdo da sua tela, que aparece o nome 50minutos como o database corrente.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

11

O QUE UMA TABELA


Uma Tabela um objeto bidimensional, composta por Colunas e Linhas, onde os dados so armazenados dentro de um database.

O exemplo abaixo exibe uma Tabela chamada Cliente, formada pelas Colunas Cod_Cli que representa um cdigo definido para o cliente, Nome_Cli que representa o nome do cliente e Renda_Cli, que representa um valor para a renda dos clientes .

Nesta Tabela ainda h 2 Linhas de dados inseridas. Temos o cliente cujo cdigo o nmero 1 e o nome Agnaldo e o cliente de nmero 2 cujo nome Renata:

Cod_Cli Nome_Cli Renda_Cli 1 2 Agnaldo Renata 30000.00 5000.00

O QUE DATATYPE
Data type, ou tipo de dado, o formado no qual os dados de cada coluna de uma tabela so armazenados em disco.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

12

O Microsoft SQL Server oferece vrios datatypes que chamamos de built-in, ou seja, construdos internamente. Eles so divididos em categorias como, por exemplo, categoria dos datatypes numricos, caracteres, data, hora, etc.

Vamos utilizar alguns destes tipos de dados e, para atabela Cliente exibida acima, vamos atribuir para a coluna Cod_Cli o datatype int, que s aceitar que se insira nela, nmeros inteiros.

Para a coluna Nome_Cli vamos devinir o tipo de dado varchar(100), que s aceitar dados no formato caractere e que tenham at 100 dgitos. E para a coluna Renda_Cli vamos utilizar o datatype decimal(10,2), que aceitar dados numricos com duas casas decimais.

Para que voc possa criar esta tabela, inserir suas duas linhas de dados e exibir seu contedo, siga as instrues abaixo.

Na mesma tela e logo aps voc ter executado o comando USE [50minutos] para acessar este database, escreva os seguintes comandos:

-- Criando a tabela Cliente CREATE TABLE Cliente ( Cod_Cli Nome_Cli int varchar(100) , ,

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

13

Renda_Cli )

decimal(10,2) ,

Na sequncia, selecione apenas co comando acima e tecle F5 para execut-lo.

Para inserir os dados dos dois clientes em questo vamos utilizar o comando INSERT (que ser visto em mais detalhes em outros tpicos deste tutorial). Ento, escreva os comandos:

-- Inserindo dois Registros, ou seja, duas Linhas de dados na tabela Cliente

INSERT Cliente VALUES(1,Agnaldo,1000.00)

INSERT Cliente VALUES(2,Renata,500.00)

Neste primeiro momento, selecione cada um dos comandos acima e tecle F5 para executlo.

Obs:

a - Quando voc for inserir dados no formado caractere, voc deve escrev-los entre apostofo, como Agnaldo e Renata.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

14

b - Voc poderia ter selecionado os dois INSERTs de uma s vez para inserir os dois clientes ao mesmo tempo, mas como voc est comeando a trabalhar com a sintaxe da SQL interessante que voc execute os comandos um a um, assim se, por acaso, voc cometer algum erro der sintaxe fica mais fcil detect-lo e corrig-lo.

c - Voc pode escrever qualquer comando da sintaxe SQL em letras maisculas ou minsculas.

d - Por causa do Collation padro da instalao do software, o SQL Server no far diferena no momento da pesquisa dos dados se, por acaso, voc digitar Agnaldo, AGNALDO, aGNALDO, etc. Enfim, o SQL Server vai gravar na Tabela os dados do jeito que voc os digitar, mas por causa do Collation pado da instalao da iInstncia, da criao do database e da definio da coluna que utilizamos em Nome_Cli, para encontrar os dados ele no far diferenciao entre letras maisculas e minsculas.

e Collation o nome que se d ao conjunto de definiao de idioma, ordenao, acentuao, etc, para o armazenamento e perquisa de dados em colunas caracteres.

f Os comentrios colocados nas demonstraes sempre aparecero na cor verde e, podem ser escritos em apenas uma linha, utilizando para isso dois simbolos de subtrao (--), Ou podero ser comantrios de vrias linhas e, para tanto devero ser escritos assim:

/* Comentarios feitos em mltiplas Linhas

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

15

so chamados de Comentrios em Bloco */

Nosso prximo passo ser a exibio dos dados que acabaram de ser inseridos. Para tanto, na mesma tela, escreva o comando abaixo:

SELECT * FROM Cliente

Selecione apenas a linha acima e pressione F5 para execut-la. Note que os dados so exibidos na parte inferior da sua tela.

Pronto! Agora voc j tem um database, uma tabela com trs colunas, e duas linhas de dados inseridas!

Se voc chegou at aqui, parabns pelos primeiros passos na sintaxe SQL da Microsoft.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

16

DML SELECT, INSERT, UPDATE E DELETE


Como foi visto anteriormente, DML um grupo de comandos da linguagem SQL que significa Data Manipulation Language Linguagem de Manipulao de Dados. Dela fazem parte os comandos SELECT, INSERT, UPDATE e DELETE.

UTILIZAO DO COMANDO SELECT


Como voc j deve ter percebido, SELECT o comando da liguagem SQL que utilizamos para selecionar/exibir os dados de uma tabela.

A sintaxe da SQL nos permite exibir dados de vrias maneiras atavs das vriaes do comando SELECT.

Para que voc possa conhecer estas possibilidades de sintaxe vamos criar, no database 50minutos, uma outra tabela chamada Funcionario, vamos inserir nela cinco linhas de dados e assim trabalhar com este objeto.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

17

------------------------------------------------------------------------ Acessando o database 50minutos Use 50minutos ------------------------------------------------------------------------ Criando a tabela Funcionrio CREATE TABLE Funcionario ( Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func ) --- Inserindo dados na tabela Funcionario INSERT Funcionario VALUES(1,'Marcos','M',1575.87,Getdate()) INSERT Funcionario VALUES(2,'Paulo','M',2500.50,Getdate()) INSERT Funcionario VALUES(3,'Roberta','F',1000.80,Getdate()) INSERT Funcionario VALUES(4,'Cristina','F',578.25,Getdate()) INSERT Funcionario VALUES(5,'Jos','M',600.00,Getdate()) ---------------------------------------------------------------------int varchar(100) char(1) Decimal(10,2) Datetime , , , , ,

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

18

EXIBINDO OS DADOS DE TODAS AS COLUNAS DA TABELA FUNCIONARIO


Para exibir os dados de todas as colunas de uma determinada tabela voc pode utilizar uma das duas sintaxes exibidas abaixo.

1 Exibindo os dados de todas as colunas de uma tabela utilizando asterisco para represent-las:

--Exibindo os dados de todas as colunas de uma tabela SELECT * FROM Funcionario

2 Exibindo os dados de todas as colunas de uma tabela especificando o nome de uma por uma:

--Exibindo os dados de todas as colunas de uma tabela SELECT Cod_Func, Nome_Func, Sexo_Func, Sal_Func, Data_Func FROM Funcionario

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

19

3 - Exibindo os dados de todas as colunas de uma tabela na ordem desejada

Voc j deve ter percebido que para exibir os dados de todas as colunas da tabela em outra ordem que no seja a da definio de sua estrutura, basta escrever o nome das colounas na sequncia em que desejar exib-las.

-- Exibindo os dados de todas as colunas de uma tabela na sequncia -- -- desejada SELECT Sexo_Func, Data_Func, Cod_Func, Nome_Func, Sal_Func FROM Funcionario

4 Exibindo os dados de algunas colunas de uma tabela

Agora ficou fcil, para exibir os dados de alguns colunas de uma tabela, basta escrever apenas seus nomes no comando SELECT e execut-lo.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

20

Exemplo_01 -- Exibindo os dados de algumas colunas de uma tabela -- na sequncia desejada SELECT Cod_Func, Nome_Func, Data_Func FROM Funcionario

Exemplo_02 -- Exibindo os dados de algumas colunas de uma tabela -- na sequncia desejada SELECT Data_Func, Cod_Func, Nome_Func FROM Funcionario

5 Exibindo dados de uma tabela utilizando Alias no nome das colunas Demonstrao das sintaxes disponveis no Microsoft SQL Server

Se voc observou os dados retornados pelo SQL Server quando executou qualquer um dos comandos acima, deve ter observado que ele apresenta a primeira linha resposta com o prprio nome atribudo cada uma das colunas, que no nosso caso : Cod_Func, Nome_Func, Sexo_Func, Sal_Func e Data_Func.
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

21

normal que os desenvolvedores de banco de dados atribuam nomes abreviados para as colunas de suas tabelas pois mais fcil trabalhar com nomes curtos ao escrever as queries.

S que isso pode no ficar claro para o usurio que vai utilizar, por exemplo, um relatrio se voc deixar que estes nomes se apresentem para ele como esto na definio da estrutura da tabela.

Ns sabemos, por exemplo, o que armazena a coluna Sal_Func, mas para um usurio pode ser que no esteja claro que ela representa o salrio de cada funcionrio inserido neste objeto.

Assim sendo, para que possamos gerar relatrios mais claros para nossos usurios podemos atribuir apelidos para os nomes de cada uma das colunas. Estes apelidos so chamados de Alias e a Microsoft nos permite escrever os alias de vrias maneiras.

Estas maneiras so exibidas abaixo.

-- Atribuindo apelidos s colunas de uma tabela -- Primeira sintaxe: SELECT Cod_Func Nome_Func Sexo_Func Sal_Func AS Cdigo, AS Nome, AS Sexo, AS Salrio,
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

22

Data_Func FROM Funcionario

AS Data

--Segunda Sintaxe: SELECT Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func FROM Funcionario Cdigo, Nome, Sexo, Salrio, Data

-- Terceira Sintaxe: SELECT Cdigo Nome Sexo Salrio Data FROM Funcionario = = = = = Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func , , , ,

-- Quarta sintaxe: SELECT Cod_Func AS [Cdigo do Funcionario],

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

23

Nome_Func Sexo_Func Sal_Func Data_Func FROM Funcionario

AS [Nome do Funcionario], AS [Sexo do Funcionario], AS [Salrio do Funcionario], AS [Data do Funcionario]

-- Quinta Sintaxe: SELECT Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func FROM Funcionario AS "Cdigo do Funcionario", AS "Nome do Funcionario", AS "Sexo do Funcionario", AS "Salrio do Funcionario", AS "Data do Funcionario"

-- Sexta Sintaxe: SELECT Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func FROM Funcionario AS 'Cdigo do Funcionario', AS 'Nome do Funcionario', AS 'Sexo do Funcionario', AS 'Salrio do Funcionario', AS 'Data do Funcionario'

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

24

--Stima Sintaxe: SELECT Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func FROM Funcionario [Cdigo do Funcionario], [Nome do Funcionario], [Sexo do Funcionario], [Salrio do Funcionario], [Data do Funcionario]

--Oitava Sintaxe: SELECT Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func FROM Funcionario "Cdigo do Funcionario", "Nome do Funcionario", "Sexo do Funcionario", "Salrio do Funcionario", "Data do Funcionario"

--Nona Sintaxe: SELECT Cod_Func Nome_Func Sexo_Func 'Cdigo do Funcionario', 'Nome do Funcionario', 'Sexo do Funcionario',

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

25

Sal_Func Data_Func FROM Funcionario

'Salrio do Funcionario', 'Data do Funcionario'

-- Dcima Sintaxe: SELECT [Cdigo do Funcionario] [Nome do Funcionario] [Sexo do Funcionario] [Salrio do Funcionario] [Data do Funcionario] FROM Funcionario = = = = = Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func , , , ,

-- Dcima primeira Sintaxe: SELECT "Cdigo do Funcionario" "Nome do Funcionario" "Sexo do Funcionario" "Salrio do Funcionario" "Data do Funcionario" FROM Funcionario = = = = = Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func , , , ,

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

26

-- Decima Sengunda Sintaxe SELECT 'Cdigo do Funcionario' 'Nome do Funcionario' 'Sexo do Funcionario' 'Salrio do Funcionario' 'Data do Funcionario' FROM Funcionario = Cod_Func = Nome_Func = Sexo_Func = Sal_Func = Data_Func , , , ,

Obs.: claro que, apenas na execuo de um nico SELECT, podemos utilizar as sintaxes exibidas acima misturadas umas com as outras, mas lgicamente muito melhor, muito mais elegante que se tenha um padro para a sua utilizao.

6 Exibindo dados de colunas virtuais

Se voc observar, a tabela Funcionario no possui, em sua estrutura, a coluna Nacionalidade. Mas suponha que, por um motivo qualquer, voc precise exibir a coluna Nacionalidade onde nos dados aparece a palavra Basileira para todos as pessoas inseridas nesta tabela.

Voc poderia acrescentar esta nova coluna na tabela executando, para tanto, o comando ALTER TABLE. Mas aqui no o caso. Suponha que voc deseja apenas exibir a nacinalidade brasileira para todos os funcionrios apenas uma niva vez.

Sendo assim, basta que voc execute um dos comandos abaixo:


Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

27

-- Exibindo todas as colunas mais uma virtual SELECT *,'Brasileira' FROM Funcionario AS Nacionalidade

-- Exibindo todas as colunas mais uma virtual SELECT Cod_Func Nome_Func Sexo_Func Sal_Func Data_Func 'Brasileira' FROM Funcionario AS Cdigo, AS Nome, AS Sexo, AS Salrio, AS Data, AS Nacionalidade

-- Exibindo algumas colunas e uma virtual SELECT Cod_Func Nome_Func Sexo_Func 'Brasileira' FROM Funcionario AS Cdigo, AS Nome, AS Sexo, AS Nacionalidade

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

28

Obs.: Com relao ao apelido das colunas, obviamente voc poder utilizar, das sintaxes apresentadas anteriormente, aquela que desejar. Para efeito de demonstrao neste tutorial estamos utilizando a primeira das sintaxes exibidas no tem 3.5.

7 Exibindo clculos em colunas virtuais

Agora vamos supor que voc precise exibir quanto seria o novo salrio de cada funcionrio se lhes fosse aplicado um aumento de 10% e um aumento salarial de 20%. S que, na realidade, voc no deseja realmente aplicar o aumento promovendo uma alterao nos dados, voc deseja apenas visualizar os novos valores.

Sendo assim, voc consegue os resultados desejados escrendo o comando abaixo.

-- Exibindo aumento de salrio com colunas virtuais SELECT Cod_Func Nome_Func Sal_Func Sal_Func Sal_Func 'Brasileira' FROM Funcionario * 1.1 * 1.2 AS Cdigo, AS Nome, AS [Salrio Real], AS [Salrio com 10%], AS [Salrio com 20%], AS Nacionalidade

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

29

Observe tambm que possvel exibir colunas virtuais como o caso da nacionalidade e como o caso dos aumentos salariais num mesmo SELECT.

-- Exibindo aumentos de salrio e a nacionalidade com colunas virtuais SELECT Cod_Func Nome_Func Sal_Func Sal_Func Sal_Func 'Brasileira' FROM Funcionario * 1.1 * 1.2 AS Cdigo, AS Nome, AS [Salrio Real], AS [Salrio com 10%], AS [Salrio com 20%], AS Nacionalidade

8 Exibindo apenas uma vez os dados repetidos de uma tabela DISTINCT

Para a demonstrao deste tpico, insira os dados abaixo, na tabela Funcionario.

INSERT Funcionario VALUES(6,'Marcia','F',1575.87,Getdate()) INSERT Funcionario VALUES(7,'Paula','F',2500.50,Getdate()) INSERT Funcionario VALUES(8,'Roberto','M',1000.80,Getdate()) INSERT Funcionario VALUES(9,'Cristian','M',578.25,Getdate()) INSERT Funcionario VALUES(10,'Mariana','F',600.00,Getdate())

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

30

INSERT Funcionario VALUES(11,'Roberto','M',1000.80,Getdate()) INSERT Funcionario VALUES(12,'Cristian','M',578.25,Getdate()) INSERT Funcionario VALUES(13,'Mariana','F',600.00,Getdate())

Se voc observar, inserimos alguns valores repetidos na tabela Funcionario. Sendo assim, temos mais de um funcionario com o mesmo nome, mais de um com o mesmo valor salarial e, mais de um funcionario do sexo feminino, como mais de um do sexo masculino.

Existe uma clusula na liguagem SQL, utilizada com o comando SELECT, que nos permite exibir apenas uma vez os valores que estiverem repetidos nos dados a serem exibidos.

Por exemplo, ao executarmos a query abaixo, o SQL Sever nos retornar apenas uma vez a letra F e apenas uma vez a letra M, muito embora as duas letras tenham sido inseridas vrias vezes na mesma coluna.

SELECT DISTINCT Sexo_Func FROM Funcionario

A query abaixo exibir apenas uma vez cada valor inserido. Sendo assim considerando, por exemplo, que o salrio de 2500,00 tenha sido inserido duas vezes na tabela, o comando abaixo apresentar este valor apenas uma vez.

SELECT DISTINCT Sal_Func FROM Funcionario

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

31

A query abaixo exibir apenas uma vez os dados repetidos considerando os valores das duas colunas a seram exibidas.

SELECT DISTINCT Nome_Func,Sal_Func FROM Funcionario

Portanto, quando quiser daber quais os valores existentes em um determinado conjunto de dados a serem retornados e quiser ver apenas uma vez cada conjunto destes valores, utiliza a clusula DISTINCT para isso.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

32

UTILIZAO DO COMANDO INSERT


Como voc j deve ter percebido, INSERT o comando da liguagem SQL que utilizamos para incluir os dados de uma tabela.

Para que voc possa conhecer estas possibilidades de sintaxe da utilizao deste comando vamos acessar o database [50minutos], e fazer algumas demonstraes, utilizando para isso, a tabela Funcionario, j criada anteriormente Para tanto, abra uma nova query no SQL Server Management Studio e em seguida execute os comandos abaixo, selecionando-os um a um e teclando F5 para cada nova execuo.

1 INSERT e INSERT INTO

Quando trabalhamos com a linguagem SQL do Microsoft SQL Server, nos acostumamos a inserir dados em uma tabela escrevendo apenas a seguinte clusula:

INSERT <NomeTabela> VALUES(valores para cada coluna separados por vrgula).

Acontece que, o comando da linguagem SQL ANSI pra incluso de dados em uma determinada tabela na verdade INSERT INTO.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

33

INSERT INTO <NomeTabela> VALUES(valores para cada coluna separados por vrgula).

Ento voc j deve ter percebido que a sintaxe SQL da Microsoft nos permite omitir a clusula INTO na execuo de incluses de dados nas tabelas de um sistema.

Execute os cdigos abaixo e perceba que os dois vo funcionar perfeitamente e inserem os mesmos dados, do mesmo jeito na tabela Funcionario:

-- INSERT e INSERT INTO INSERT Funcionario VALUES(1,'Marcos','M',1000.00,Getdate()) GO INSERT INTO Funcionario VALUES(1,'Marcos','M',1000.00,Getdate())

2 INSERT Posicional e INSERT Declarativo

Chamamos de INSERT Posicional o comando que insere dados em uma tabela passando os valores para as colunas na mesma ordem em que foram escritas na criao da mesma.

Neste caso no h a necessidade de escrever o nome de cada coluna onde estamos inserindo os valores, pois presume-se que estamos passando-os na sequncia de sua criao.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

34

Observe o cdigo abaixo:

-- Insert Posicional sem a clusula INTO INSERT Funcionario VALUES(1,'Marcos','M',1000.00,Getdate())

-- Insert Posicional com a clusula INTO INSERT INTO Funcionario VALUES(1,'Marcos','M',1000.00,Getdate())

J no INSERT Declarativo, como o prprio nome j indica, ns declaramos a ordem das colunas na qual passaremos os valores durante uma incluso de dados.

Esta forma de escrita do comando INSERT interessante porque nos permite inserir os dados para as colunas passando os valores na sequncia em que desejarmos, sem a necessidade de obedecer a order utilizada na criao da tabela. Observe:

-- Insert Declarativo sem a clusula INTO INSERT Funcionario (Sexo_Func,Data_Func,Cod_Func,Sal_Func, Nome_Func) VALUES('M',GETDATE(),1,1000.00,'Marcos')

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

35

-- Insert Declarativo com a clusula INTO INSERT INTO Funcionario (Sexo_Func,Data_Func,Cod_Func,Sal_Func, Nome_Func) VALUES('M',GETDATE(),1,1000.00,'Marcos')

A utilizao do INSERT Declarativo til quando queremos inserir dados em apenas algumas colunas da tabela, fazendo com que o SQL Server insira nas colunas restantes valores nulos ou valores padro (default) se houver algum declarado para estas culunas.

Observe o cdigo abaixo, onde estamos omitindo a incluso de dados para a coluna Data_Func.

INSERT Funcionario (Cod_Func,Sal_Func, Nome_Func) VALUES(1,1000.00,'Marcos')

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

36

3 INSERT com uma clusula VALUES

A partir da verso 2008 do Microsoft SQL Server podemos utilizar a sintaxe abaixo, onde escrevemos apenas uma vez o comando completo e na sequncia passamos apenas uma lista de valores que desejamos inserir de uma s vez.

Observe que podemos utilizar ou no a clusula INTO aqui tambm.

INSERT Funcionario VALUES (1,'Marcos','M',1575.87,Getdate()), (2,'Paulo','M',2500.50,Getdate()), (3,'Roberta','F',1000.80,Getdate()), (4,'Cristina','F',578.25,Getdate()), (5,'Jos','M',600.00,Getdate())

4 INSERT com SELECT

A composio do comando SELECT com o comando INSERT utilizada para copiar dados de uma tabela para outra.

Podemos utilizar estes nos comandos nos seguintes casos:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

37

Caso_01 Estruturas iguais

Suponha que voc tenha criado a tabela Empregado, cuja estrutura segue no cdigo abaixo, e que precise copiar para ela os dados da tabela Funcionario.

CREATE TABLE Empregado ( Cod_Emp Nome_Emp Sexo_Emp Sal_Emp Data_Emp ) int varchar(100) char(1) Decimal(10,2) Datetime , , , , ,

Observando que a estrutura das duas tabelas a mesma, podemos escrever o comando abaixo para realizar a cpia desejada:

INSERT Empregado SELECT * FROM Funcionario

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

38

Caso_02 Estruturas diferentes, com a tabela que recebe os dados tendo menos colunas que a tabela origem.

Suponha agora qua a tabela para a qual voc deseja copiar dados seja essa cujo cdigo segue abaixo.

CREATE TABLE Auxiliar ( Cod_Aux Nome_Aux Sexo_Aux ) int varchar(100) , char(1) , ,

Note que neste caso temos que utilizar o comando SELECT, obtendo da tabela Funcionrio apenas os dados que correspondem s colunas da tabela Auxiliar.

INSERT Auxiliar SELECT Cod_Func,Nome_Func,Sexo_Func FROM Funcionario

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

39

Caso_03 Estruturas diferentes, com a tabela que recebe os dados tendo mais colunas que a tabela origem.

Agora voc tem a tabela Auxiliar, com uma coluna (Nac_Estag Nacionalide do Estagirio) para a qual no h valor na tabela origem.

CREATE TABLE Estagiario ( Cod_Estag int ,

Nome_Estag varchar(100) , Sexo_Estag Sal_Estag Data_Estag Nac_Estag ) char(1) , Decimal(10,2) , Datetime ,

varchar(100) ,

Ento para copiar dados de Funcionario para Estagirio teremos que utilizar um dos comandos abaixo:

-- Inserindo um catactere em branco na coluna Nac_Estag INSERT Estagiario SELECT *, ' ' FROM Funcionario

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

40

-- Inserindo a palavra Brasileirana coluna Nac_Estag INSERT Estagiario SELECT *, 'Brasileira' FROM Funcionario

-- Inserindo um valor Nulo na coluna Nac_Estag INSERT Estagiario SELECT *, Null FROM Funcionario

Poderamos tambm utiilizar a palavra Default no lugar da coluna Nac_Estag, se na tabela Estagirio houvesse um valor definido para ela. A sintaxe seria essa:

-- Inserindo o valor Default na coluna Nac_Estag INSERT Estagiario SELECT *, Default FROM Funcionario

Caso_04 Quando a tabela que recebe os dados tem coluna que pode receber Null ou Default

Neste caso voc utilizaria o INSERT Declarativo para passar os valores desejados.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

41

Vamos Supor que na tabela Estagirio, j haja um valor Default definido para a coluna Nac_Estag e que voc deseje inserir um valor nulo para a Data_Estag.

Ento seu comando deveria ser escrito assim

-- Inserindo dados na tabela Estagiario, deixando que o prprio SQL valores nas colunas Nac_Estag e Data_Estag INSERT Estagiario (Cod_Estag,Nome_Estag,Sexo_Estag,Sal_Estag) SELECT Cod_Func, Nome_Func,Sexo_Func,Sal_Func FROM Funcionario

-- Server insira

Obs.: Quando inserimos um Null em uma coluna estamos determinando que o SQL Server a deixe sem valor algum. Portanto Null quer dizer ausncia de valor!

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

42

UTILIZAO DO COMANDO UPDATE


UPDATE o comando que utilizamos para modificar os dados em uma ou mais colunas.

1 A clusula SET

Em todo e qualquer comando UPDATE voc dever escrever UMA clusula SET, para se referenciar a(s) coluna(s) que deseja alterar.

Por exemplo: no script abaixo, estamos criandos uma tabela chamada Pessoa no database [50minutos]. Estamos tambm inserindo cinco registro nesta tabela.

----------------------------------------------------------------------Use [50Minutos] ----------------------------------------------------------------------CREATE TABLE Pessoa ( Cod_Pes Nome_Pes Sexo_Pes Sal_Pes Data_Pes int varchar(100) char(1) Decimal(10,2) Datetime , , , ,
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

43

) ----------------------------------------------------------------------- Inserindo dados na tabela Pessoa INSERT Pessoa VALUES(1,'Marcos','M',1000.00,Getdate()) INSERT Pessoa VALUES(2,'Paulo','M',1000.00,Getdate()) INSERT Pessoa VALUES(3,'Roberta','F',1000.00,Getdate()) INSERT Pessoa VALUES(4,'Cristina','F',1000.00,Getdate()) INSERT Pessoa VALUES(5,'Jos','M',1000.00,Getdate()) ----------------------------------------------------------------------

Suponha que voc precise modificar o valor da coluna Sal_Pes aplicando para todas as pessoas da tabela um aumento salarial de 10%. Para tanto voc teria que escrever um comando UPDATE. Veja abaixo:

UPDATE Pessoa SET Sal_Pes = Sal_Pes * 1.1

Suponha agora que voc precise modificar os dados da tabela pessoa da seguinte maneira:

a) Acrescente o sobrenome da Silva para todas as pessoas, b) Altere o valor da coluna Sexo_Pes para X c) Aplique mais 500.00 de aumento salarial para todos.
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

44

O comando UPDATE para este caso tem que ser escrito assim:

UPDATE Pessoa SET Nome_Pes = Nome_Pes + 'da Silva', Sexo_Pes = 'x', Sal_Pes = Sal_Pes + 500.00

2 A clusula FROM

Para o comando UPDATE a clusula FROM opcional. Portanto voc poderia escrever os UPDATEs anteriores assim, se quisesse:

------------------------------------------------------------------------ Utilizando a clusula FROM UPDATE Pessoa SET Sal_Pes = Sal_Pes * 1.1 FROM Pessoa -----------------------------------------------------------------------

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

45

UPDATE Pessoa SET Nome_Pes = Nome_Pes + 'da Silva', Sexo_Pes = 'x', Sal_Pes = Sal_Pes + 500.00 FROM Pessoa -----------------------------------------------------------------------

UTILIZAO DO COMANDO DELETE


com o comando DELETE que exclumos dados de uma tabela.

possvel excluir valores de apenas uma coluna? Se esta for tambm a sua dvida, s pensar que o comando DELETE excluir linhas da tabela. No d para excluir valor de apenas uma coluna. Podemos sim alterar o valor da mesma, mas quando se trata de DELETE ele retirar da tabela os valores de uma (ou mais) linha(s) inteira(s)!

1 DELETE com e sem a clsula FROM Para o comando UPDATE a Microsoft aceita as trs formas de sintaxe abaixo: -- Excluindo dados da tabela Pessoa DELETE Pessoa DELETE Pessoa FROM Pessoa DELETE FROM Pessoa

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

46

Obs:

a) DELETE difererente de DROP. O comando DROP elimina objetos de um database. Por exemplo, se voc executar o comando DROP TABLE Pessoa, estar eliminando a tabela do database! J o comando DELETE, como visto logo acima, exclui apenas os dados.

b) At este momento, quando utilizamos os comandos SELECT, UPDATE e DELETE, afetamos todos os registros da tabela. Talvez voc esteja se perguntando como temos que fazer para ler, alterar e excluir apenas alguns registros da tabela e no todos. Bom, neste caso voc teria que utilizar a clusula WHERE, que o nosso prximo assunto.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

47

A CLUSULA WHERE
A clusula WHERE utilizada da mesma forma, ou seja, com a mesma sintaxe para os comandos SELECT, UPDATE e DELETE.

Ela serve para que possamos escolher qual (ou quais) registro(s) da(s) tabela(s) desejamos ler, alterar ou eliminar.

Para que possamos escolher quais registros desejamos que nosso comando afete vamos precisar utiilizar operadores para fazer a seleo dos mesmos.

1 Operadores e Critrios de Pesquisa

atravs dos operadores que podemos dizer para o SQL Server qual dados deve ser afetado pelos comandos DML.

Para que possamos fazer demonstraes da utilizao da clusula WHERE vamos executar o script abaixo, que cria uma tabela chamada Produto, no database [50minutos] e insere 10 registros de dados.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

48

----------------------------------------------------------------------Use [50minutos] ----------------------------------------------------------------------CREATE TABLE Produto ( Cod_Prod Nome_Prod Tipo_Prod Qtd_Prod Val_Prod ) INSERT Produto VALUES(1,'Geladeira','Cozinha',500,1500.00) INSERT Produto VALUES(2,'Armrio','Cozinha',700,300.00) INSERT Produto VALUES(3,'Sof','Sala',200,1200.00) INSERT Produto VALUES(4,'Cama','Quarto',300,500.00) INSERT Produto VALUES(5,'Fogo','Cozinha',400,700.00) INSERT Produto VALUES(6,'Guarda-Roupa','Quarto',500,1000.00) INSERT Produto VALUES(7,'Poltrona','Sala',600,Null) INSERT Produto VALUES(8,'Estante','Sala',800,400.00) INSERT Produto VALUES(9,'Penteadeira','Quarto',200,300.00) INSERT Produto VALUES(10,'Cadeira','Cozinha',1000,150.00) int, char(50), char(20), int, decimal(10,2)

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

49

Os operadores de comparao so:

Igual Diferente Maior Maior ou Igual Menor Menou ou Igual No Maior No Menor (!<)

(=) (<> ou !=) (>) (>=) (<) (<=) (!>)

Vejamos alguns exemplo:

a) Suponha que voc deseje obter os dados da tabela Produto, mas apenas do Produto cujo cdigo igual a 1. Para tento voc teria que escrever o comando abaixo:

SELECT * FROM Produto WHERE Cod_Prod = 1

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

50

b) Se desejasse exibir apenas os dados dos Produtos do tipo Cozinha, teria que escrever o commando a seguir:

SELECT * FROM Produto WHERE Tipo_Prod = 'Cozinha'

Operadores Lgicos E Ou Negao (AND) (OR) (NOT)

Obviamente possivel escrever mais de uma condio para a clusula WHERE, como no exemplo abaixo, onde desejamos obter todos os dados do Produto do tipo `Cozinha, mas que tenham tambm o valor maior do que 500.00.

Para atingir este objetivo escrevemos o comando abaixo:

SELECT * FROM Produto WHERE Tipo_Prod = 'Cozinha' AND Val_Prod > 500.00

Poderamos tambm querer exibir todos os valores dos Produto to tipo Cozinha OU dos Produtos com valor acima de 500.00.
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

51

Para tanto precisaramos escrever o comando abaixo:

SELECT * FROM Produto WHERE Tipo_Prod = 'Cozinha' OR Val_Prod > 500.00

E assim, segue. Se voc precisar, poder colocar quantas condies precisar na clusula WHERE, sendo que se houver mais de uma, elas devero ser escritas utilizando os operadores lgicos AND e/ou OR.

Se voc precisasse de todos os produtos que no forem do tipo Cozinha poder| escrever o cdigo abaixo:

SELECT * FROM Produto WHERE Tipo_Prod != 'Cozinha'

Ou poder substitui-lo por este:

SELECT * FROM Produto WHERE Tipo_Prod <> 'Cozinha'

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

52

Eu poderia escrever a query abaixo para obter todos os produtos que o valor no seja maior do que 500.00:

SELECT * FROM Produto WHERE Val_Prod !> 500.00

Eu conseguiria obter os mesmos dados com o commando que segue:

SELECT * FROM Produto WHERE Val_Prod <= 500.00

Suponha que voc queira exibir os dados dos Produtos cujos cdigos sejam 2, 4 e 6. Voc deseja obter da tabela os trs produtos. Para conseguir isso ter que escrever o cdigo abaixo:

SELECT * FROM Produto WHERE Cod_Prod = 2 OR Cod_Prod = 4 OR Cod_Prod = 6

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

53

Operadores para tartar conjunto de valores

Mas com se utilizar o critrio de pesquisa IN poder substituir o codigo anterior pelo que segue e conseguir os mesmos dados.

SELECT * FROM Produto WHERE Cod_Prod IN (2,4,6)

Imagine agora que seja necessrio que voc obtenha da tabela todos os Produtos menos os de cdigo 2, 4 e 6. Pata tanto ter que escrever o cdigo abaixo:

SELECT * FROM Produto WHERE Cod_Prod <> 2 AND Cod_Prod <> 4 AND Cod_Prod <> 6

Mas com se utilizar NOT IN poder obter os mesmos valores.

SELECT * FROM Produto WHERE Cod_Prod NOT IN (2,4,6)

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

54

Operadores para faixas de Valores

O comando abaixo nos dar todos os produtos cujo valor estejam na faixa de 500.00 e 2000.00 (inclusive os produtos que custarem 500.00 e 2000.00).

SELECT * FROM Produto WHERE Val_Prod >= 500.00 AND Val_Prod <= 2000.00

Os mesmos dados podem ser obtidos utilizando-se o critrio de pesquisa BETWEEEN:

SELECT * FROM Produto WHERE Val_Prod BETWEEN 500.00 AND 2000.00

O comando abaixo nos dar todos os produtos cujo valor estejam fora da faixa de 500.00 e 2000.00:

SELECT * FROM Produto WHERE Val_Prod < 500.00 OR Val_Prod > 2000.00

Os mesmos dados podem ser obtidos utilizando-se os critrios de pesquisa NOT BETWEEEN:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

55

SELECT * FROM Produto WHERE Val_Prod NOT BETWEEN 500.00 AND 2000.00

Operadores para tartar colunas do tipo charactere

Escrevendo o SELECT abaixo obtemos todos os Produtos cujo nome seja exatamente Geladeira:

SELECT * FROM Produto WHERE Nome_Prod = 'Geladeira'

Porm se desejarmos obter todos os produtos que o nome comece, contenha ou termine com uma determinada letra ou slaba teremos que utilizar o crtrio de pesquisa LIKE e para obter os dados negando a existncia dos mesmos critrios, teremos que utilizar NOT LIKE. Observe exemplos abaixo:

-- Obtendo todos os Produtos cujo nome comea com a legra G. SELECT * FROM Produto WHERE Nome_Prod LIKE 'G%'

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

56

-- Obtendo todos os Produtos que tenha as slabas eira em qualquer incio, meio ou fim. SELECT * FROM Produto WHERE Nome_Prod LIKE '%eira%'

-- posio,

-- Selecione todos os Produtos cujo nome termine com a letra O. SELECT * FROM Produto WHERE Nome_Prod LIKE '%o'

-- Selecione os dados de todos os produtos onde o nome tenha at cinco letras. Observe que cada letra representada aqui por um trainho SELECT * FROM Produto WHERE Nome_Prod LIKE '_____'

-- Selecione todos os Produtos, onde o nome No comece com a letra G, SELECT * FROM Produto WHERE Nome_Prod NOT LIKE 'G%'

-- Obtendo todos os Produtos que No tenha as slabas eira em -- qualquer posio, incio, meio ou fim. SELECT * FROM Produto WHERE Nome_Prod NOT LIKE '%eira%'
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

57

-- O exemplo a seguir exibe todos os Produtos cujo nome comece com -- qualquer letra, contenha a sequncia de letrar ei e contenha logo -- em seguida, qualquer letra, diferente de a. SELECT * FROM Produto WHERE Nome_Prod LIKE '%ei_%'ESCAPE 'a'

-- O exemplo abaixo exibe os dados de todos os produtos, cujo nome no -- Nulo SELECT * FROM Produto WHERE Nome_Prod IS NOT NULL

-- O exemplo abaixo exibe os dados de todos os produtos, cujo nome -- Nulo SELECT * FROM Produto WHERE Nome_Prod IS NULL

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

58

Resumo dos Critrios de Avaliao

Critrio IN / NOT IN

Resumo Pesquisa dados em uma tabela com base na existncia [ou no] dos mesmos em uma lista de valores, Pesquisa dados em uma tabela com base na existncia [ou no] dos mesmos em uma faixa de valores. Pesquisa dados em uma tabela, verificando sua existncia [ou no] comparando-os com palavras ou parte delas em uma determinada coluna. O critrio SCAPE, exclui uma ou mais letras dos resultados desejados. Pesquisa dados em uma tabela com base na ausncia [ou no] de valores.

BETWEEN /NOT BETWEEN

LIKE / NOT LIKE / SCAPE

IS NULL / IS NOT NULL

Obs.:

a) Todos os exemplos exibidos anteriormente podem ser utilizados com os comandos UPDATE e DELETE com a mesma sintaxe exibida anteriormente, e podem tambm ser utilizados para compor um critrio de pesquisa mais complexo:

SELECT * FROM Produto WHERE Nome_Prod LIKE '%A'


Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

59

AND Val_Prod BETWEEN 200.00 AND 500.00 AND Qtd_Prod > 200

UPDATE Produto SET Qtd_Prod = Qtd_Prod - 200.00 WHERE Nome_Prod LIKE '%A' AND Val_Prod BETWEEN 200.00 AND 500.00 AND Qtd_Prod > 200

DELETE Produto WHERE Nome_Prod LIKE '%A' AND Val_Prod BETWEEN 200.00 AND 500.00 AND Qtd_Prod > 200

b) Podemos utilizar tambm como critrios de pesquisa as funes CONTAINS() e FREETEXT().

c) Temos tambm a possibilidade de utilizar em clusula WHERE os critrios de pesquisa ALL, SOME | ANY e EXISTS | NOT EXISTS, mas estes so escritos com subqueries. As subqueries so vistas no prximo tutorial.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

60

A CLUSULA ORDER BY
A clusula ORDER BY utilizada no comando SELECT com o intuito de exibir dados de forma ordenada.

A ordenao pode ser feita por uma ou mais coulnas, e estas podem estar armazenadas no formato numrico, caracter, data e data/hora.

Para exemplificar as explicaes sobre esta clausula, vamos criar a tabela Material no database [50minutos], como mostra o script abaixo:

----------------------------------------------------------------------Use [50minutos] ----------------------------------------------------------------------CREATE TABLE Material ( Cod_Mat int, Tipo_Mat char(1), Nome_Mat Qtd_Mat int, Val_Mat decimal(10,2) char(50),

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

61

) ----------------------------------------------------------------------INSERT Material VALUES (1,'A','Caderno Espiral',100,12.50) (2,'A','Lpis Preto',500,1.50) (3,'A','Lpis de Cor',600,7.50) (4,'A','Caneta Azul',800,5.50) (5,'B','Caneta Preta',150,5.50) (6,'B','Caderno Brochura',200,10.00) (7,'B','Borracha Macia',900,5.50) (8,'B','Borracha Colorida',1000,1.50) (9,'C','Apontador Colorido',2000,5.50) (10,'C','Rgua de Madeira',3500,9.00) (11,'C','Rgua de Plstico',2586,10.00) (12,'C','Folhas de Papel',2587,5.50) -----------------------------------------------------------------------

Se voc prestar ateno poder observar que, na coluna Nome_Mat (que representa o nome dos materiais inseridos na tabela), os dados foram inseridos sem obedecer a nenhuma ordenao especfica.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

62

Suponha ento que voc precisasse gerar um relatrio que exiba todos os dados da tabela Material em ordem alfebtica do nome.

Para cumprir com esta tarefa basta escrever e executar o cdigo abaixo:

SELECT * FROM Material ORDER BY Nome_Mat

ORDENANDO PELA POSIO DA COLUNA


Podemos orderna os dados a serem exibidos pelo nome da coluna ou pela posio da mesma em duas situaes.

Ordenando pela posio da coluna na tabela

Observe que a coluna Nome_Mat a terceira coluna da estrutura da tabela Material. Sendo assim, se voc escrever o comando abaixo, obter os dados na mesma ordenao feita anteriormente.

SELECT * FROM Material ORDER BY 3

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

63

Ordenando pela posico da coluna na lista de colunas do SELECT

O comando abaixo tambm exibe os dados ordenados pela coluna Nome_Mat, que neste caso a segunda coluna da select list.

SELECT Cod_Mat,Nome_Mat,Val_Mat FROM Material ORDER BY 2

ARGUMENTOS
Podemos utilizar argumetos em cada uma das colunas que escrevermos na clusula ORDER BY.

ASC Ascendente

Para apresentar os dados ordenados de forma crescente, portanto ascendente, utilizamos o argumento ASC, que por sinal, j o argumento utilizado como default no SQL Server.

SELECT * FROM Material ORDER BY Nome_Mat ASC

SELECT * FROM Material ORDER BY 3 ASC

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

64

Portanto escrevendo ASC, ou no, os dados sero apresentados com a mesma ordenao

DESC Decrescente

Para apresentar os dados de forma decrescente utilizamos o argumento DESC.

SELECT * FROM Material ORDER BY Nome_Mat DESC

SELECT * FROM Material ORDER BY 3 DESC

COLLATE

A ordenao feita pelo COLLATE s se aplica s colunas que tenhas os datatypes char, varchar, nchar e nvarchar.

SELECT * FROM Material ORDER BY Nome_Mat COLLATE Latin1_General_CI_AS_KS_WS

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

65

SELECT * FROM Material ORDER BY 3 COLLATE Latin1_General_CI_AS_KS_WS

Obs: Resumidamente falando, collate um conjuntos de definies referentes aos dados armazenados em colunas do tipo caractere. O collation define, por exemplo, que uma coluna caractere possa armazenar as letras e dgitos referentes um determinado idioma. O Collation define tambm a forma (binary ou dictionary) em que os dados so ordenados quando um comando order by executado sobre esta coluna. O Collation tambm define se o SQL Server far diferena, ou no, entre as letras maisculas e minsculas durante uma pesquisa, define tambm se ele far diferena entre letras acentuadas ou no.

A CLUSULA TOP
A clusula TOP utilizada para apresentar os primeiros registros a serem apresentados em uma pesquisa.

A clusula TOP tambm poder ser utilizada em pesquisas que contenham a clusula WHERE com todas as sintaxes exibidas nos tens do tpico 4. O SQL Server obtem os dados da tabela de acordo com os critrios da clusula WHERE e exibe os n primeiros registros, conforme especificado logo aps a clusula TOP.

TOP N
A letra n que acompanha a clusula TOP uma expresso numrica que representa a quantidade de primeiros registros que se deseja obter em uma pesquisa. Observe os exemplos que seguem:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

66

-- Apresenta o primeiro registro deste conjunto de dados SELECT TOP 1 * FROM Material

-- Apresenta os dois primeiros registros deste conjunto de dados SELECT TOP 2 * FROM Material

-- Apresenta os trs primeiros registros deste conjunto de dados SELECT TOP 3 * FROM Material

TOP N PERCENT
As clusulas TOP n PERCENT so utilizadas para que o SQL Server obtenha exiba os n por cento (n%) dos dados retornados por uma deterimanda pesquisa

-- Apresenta 10% dos registro retornados por este SELECT SELECT TOP 10 PERCERNT * FROM Material

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

67

-- Apresenta 20% dos registro retornados por este SELECT SELECT TOP 20 PERCENT * FROM Material

TOP N , TOP N PERCENT WITH TIES COM ORDER BY


A clusula WITH TIES pode ser utilizada com TOP n e com TOP n PERCENT, mas dever ser acompanhada pelas clusulas ORDER BY.

O SQL Server apresenta os n primeiros registros (com base no valor absoluto ou no percentual) trazendo os outros registros cujo valor da coluna escrita na clusula ORDER BY seja igual ao valor do ltimo registro apresentado.

Por exemplo, no comando abaixo, sero apresentados os cinco primeiros registros da tabela material, porm outras linhas de dados podero ser exibidas se houver outros registros cujo valor do material(Val_Mat) seja igual ao valor do quinto material deste conjunto de valores.

SELECT TOP 5 WITH TIES Nome_Mat,Val_Mat FROM Material ORDER BY Val_Mat

Estas clusulas so teis para se obter, por exemplo, o material mais caro ou mais barato desta tabela. Observe os exemplos:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

68

-- Exibindo os materiais mais baratos da tabela SELECT TOP 1 WITH TIES Nome_Mat,Val_Mat FROM Material ORDER BY Val_Mat

-- Exibindo os materiais mais caros da tabela SELECT TOP 1 WITH TIES Nome_Mat,Val_Mat FROM Material ORDER BY Val_Mat DESC

TOP N COM UPDATE E DELETE


Voc tambm pode utilizar a clusula TOP com os comandos UPDATE e DELETE para dizer para o SQL Server alterar ou excluir os n primairos registros de uma tabela.

-- Aumenta em 10% o valor dos 5 primeiros materiais da tabela UPDATE TOP 5 Materiais SET Val_Mat = Val_Mat 1.1

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

69

-- Exclui os 3 primeiros materiais da tabela DELETE TOP 3 FROM Materiais

A CLUSULA OUTPUT
A clusula OUTPUT serve para que voc possa obter os dados antes, ou depois, deles serem alterados ou excludos de uma tabela.

Obter os dadosquer dizer exibi-los ou salva-los em uma outra tabela.

Para exemplificar a clusula vamos utilizar a tabela abaixo com os dados que seguem:

---------------------------------------------------------------------Use [50minutos] ---------------------------------------------------------------------CREATE TABLE Bonus ( Cod_Bonus Cod_Cli Data_Bonus Val_Bonus int, smalldatetime, decimal(10,2) int,

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

70

) ---------------------------------------------------------------------INSERT Bonus VALUES (1,2,Getdate(),50.00,) (1,1,Getdate(),150.00,) (1,3,Getdate(),80.00,) ---------------------------------------------------------------------CREATE TABLE Premio ( Cod_Premio Cod_Cli Data_Premio Val_Premio ) ---------------------------------------------------------------------int, smalldatetime, decimal(10,2) int,

Observe que a tabela Bonus recebe dados e que a tabela Premio criada, mas permanece vazia.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

71

UPDATE COM OUTPUT


-- Altera os dados da tabela, e exibe os dados de todas as colunas -- com os valores anteriores alterao UPDATE Bonus SET Val_Bonus = Val_Bonus * 1.1 OUTPUT DELETED.*

-- Altera os dados da tabela, e exibe os dados de todas as colunas -- com os valores aps alterao UPDATE Bonus SET Val_Bonus = Val_Bonus * 1.1 OUTPUT INSERTED.*

-- Altera os dados da tabela, e exibe os valores de cod_Cli e Val_Bonus -- como eles eram antes de ocorrer a alterao UPDATE Bonus SET Val_Bonus = Val_Bonus * 1.1 OUTPUT DELETED.Cod_Cli,DELETED.Val_Bonus

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

72

-- Altera os dados da tabela, e exibe os novos valores de cod_Cli e -- Val_Bonus UPDATE Bonus SET Val_Bonus = Val_Bonus * 1.1 OUTPUT INSERTED.Cod_Cli,INSERTED.Val_Bonus

-- Altera os dados da tabela, mas salva os valores antigos em outra -- tabela UPDATE Bonus SET Val_Bonus = Val_Bonus * 1.1 OUTPUT DELETED.* INTO Premio

DELETE COM OUTPUT

-- Exclui os dados da tabela Bonus e exibe os valores que foram -- excludos DELETE Bonus OUTPUT DELETED.*; ----------------------------------------------------------------------

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

73

-- Exclui os dados da tabela Bonus e exibe os valores que foram -- excludos DELETE Bonus OUTPUT DELETED.Cod_Bonus, DELETED.Val_Bonus ----------------------------------------------------------------------- Exclui todos os dados da tabela, mas os salva em outra tabela antes -- de excluir. DELETE Pessoa OUTPUT DELETED.Nome_Pes INTO Premio

GROUP BY
GROUP BY uma clusula que utilizamos para produzir totalizaes com agrupamentos de dados.

As totalizaes so feitas atravs das built-on functions Sum(), Count(), Max(), Min(), Avg(), entre outras e os agrupamentos so feitos com os argumentos HAVING, RULLUP(), CUBE(), GROUPING SET().

Para exemplificar, execute o script abaixo:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

74

----------------------------------------------------------------------USE [50minutos] ----------------------------------------------------------------------DROP TABLE Produto ----------------------------------------------------------------------CREATE TABLE Produto ( Cod_Prod Cod_Tipo int char(1) Not Null, Not Null, Not Null, Not Null, Not Null, Not Null

Cod_Linha tinyint Nome_Prod varchar(50) Qtd_Prod Val_Prod ) int decimal(10,2)

----------------------------------------------------------------------INSERT Produto VALUES(1,'A',1,'Mesa',100,500.00), (2,'B',1,'Sof',200,1500.00), (3,'A',2,'Mesa',100,200.00), (4,'A',2,'Armrio',300,200.00), (5,'C',1,'Cama',500, 1000.00), (6,'B',1,'Poltrona',100,250.00),

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

75

(7,'B',2,'Sof',200,300.00), (8,'C',2,'Cama',100,150.00), (9,'A',1,'Armrio',200,800.00), (10,'C',1,'Guarda-Roupa',100,1500.00) -----------------------------------------------------------------------

FUNES DE TOTALIZAO

FUNO AVG()

O QUE FAZ

EXEMPLO DE USO

Retorna a mdia dos valores de uma Avg(ExpressoNumrica) Expresso Numrica Retorna o nmero de linha com o Count(ExpressoNumrica) contedo diferente de Null. O seu retorno estar no formato int. Retorna o nmero total de linhas Count(*) considerando os valores nulos. O seu retorno estar no formato int. Retorna o nmero de linha com o COUNT_BIG(ExpressoNumrica) contedo diferente de Null. O seu retorno estar no formato Bigint.

COUNT()

COUNT(*)

COUNT_BIG()

COUNT_BIG(*) Retorna o nmero total de linhas COUNT_BIG(*) considerando os valores nulos. O seu retorno estar no formato Bigint.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

76

MAX() MIN() STDEV

Retorna o maior valor de uma coluna Retorna o menor valor de uma coluna

Max(ExpressoNumrica) Min(ExpressoNumrica)

Retorna o desvio padro de uma Stdev (ExpressoNumrica) expresso numrica. (Clculo Estatstico) Retorna o desvio padro populacional Dtdevp(ExpressoNumrica) de uma expresso numrica. (Clculo Estatstico) Retorna a variao estatstica de uma Var(ExpressoNumrica) expresso numrica. (Clculo Estatstico) Retorna a variao estatstica Varp(ExpressoNumrica) populacional de uma expresso numrica. (Clculo Estatstico) Cria uma nova coluna no resultado de Grouping(ExpressoNumrica) um SELECT com as clusulas GROUP BY / CUBE ou GROPUP BY/ROLLUP. A funo acrescenta o nmero 1 se o valor for resultado de uma totalizao e 0 se o valor no for resultado de uma totalizao.

STDEVP()

VAR()

VARP()

GROUPING()

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

77

UTILIZANDO GROUP BY
No nosso primeiro exemplo queremos mostrar a quantidade de produtos em estoque que temos para cada tipo de produto. Para tanto temos que executar o seguinte comando:

SELECT Cod_Tipo, Sum(Qtd_Prod) AS Qtd_Prod FROM Produto GROUP BY Cod_Tipo

Se quisssemos exibir o total de produtos em estoque por tipo e por linha de produto teramos que executar o cdigo abaixo:

SELECT Cod_Tipo,Cod_Linha, Sum(Qtd_Prod) AS Qtd_Prod FROM Produto GROUP BY Cod_Tipo,Cod_Linha

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

78

HAVING
Se quisessemos restringir o resultado apresentado no primeiro exemplo acima, ou seja, se quisessemos exibir a quantidade total em estoque dos produtos agrupador por tipo, mas desejando apresentar s os dados onde a soma das quantidades em estoque seja maior do que 500, teramos que utilizar a clusula HAVING, como segue:

SELECT Cod_Tipo, Sum(Qtd_Prod) AS Qtd_Prod FROM Produto GROUP BY Cod_Tipo HAVING Sum(Qtd_Prod) > 500

ROLLUP()
Utilizamos para apresentar subtotais e total geral em um agrupamento de dados.

O exemplo abaixo exibe a quantidade de produto em estoque por tipo e por linha de produto, dando sub-totais por tipo, sub-totaispor linha e um total geral.

SELECT Cod_Tipo,Cod_Linha, Sum(Qtd_Prod) AS Qtd_Prod FROM Produto GROUP BY ROLLUP (Cod_Tipo,Cod_Linha)


Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

79

CUBE()
Cube vai fazer com que o SQL Server gere os dados inicialmente iguais ao Rollup, s que vai exibir totalizaes de todos os agrupamentos possveis considerando as colunas escritas entre parnteses. Observe:

SELECT Cod_Tipo,Cod_Linha, Sum(Qtd_Prod) AS Qtd_Prod FROM Produto GROUP BY CUBE(Cod_Tipo,Cod_Linha)

GROUPING SET()
Grouping Sets vai produzir os mesmos dados que produziramos se utilizssemos a clusula UNION. Como ainda no falamos de UNION, a clusula GROUPING SETS apresentada neste tutorial, mas juntamente com o UNION.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

80

CASE
A clusula CASE utilizada quando desejamos executar testes de condio dentro de uma query.

Para fazermos nossas demostraes, execute o cdigo abaixo:

----------------------------------------------------------------------USE [50minutos] ----------------------------------------------------------------------DROP TABLE Cliente go ----------------------------------------------------------------------CREATE TABLE Cliente ( Cod_Cli Nome_Cli int, varchar(100),

Est_Civil char(1), Renda_Cli decimal(10,2), Nome_Cid varchar(100) )

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

81

----------------------------------------------------------------------INSERT Cliente VALUES (1,'Jos Maria','C',1500.00,'So Paulo') (2,'Maria Jos','S',2500.00,'So Paulo') (3,'Jos','D',5300.00,'Sorocaba') (4,'Maria','S',6500.00,'Jundia') (5,'Ana','C',7600.00,'So Jos do Rio Preto') (6,'Anita','C',500.00,'Araraquara') (7,'Paulo','S',2500.00,'So Carlos) (8,'Paula','S',1500.00,'So Paulo') (9,'Roberto','V',3500.00,'So Paulo') (10,'Roberta','S',4500.00,'So Paulo') -----------------------------------------------------------------------

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

82

CASE COM SELECT


fcil perceber o que a query abaixo vai exibir. Na tabela, na coluna Est_Civil (Estado Civil) ns inserimos as letras S,C,D,V para (Solteiro, Casado, Divorsiado e Vivo).

No relatrio que precisamos gerar, temos que fazedr aparecer as palavras relativas ao estado civil de cada cliente e no as letras. No desejamos modificar os dados e nem a estrutura da tabela, apenar queremos o relatrio.

Para tanto, execute o cdigo abaixo:

SELECT CASE Est_Civil WHEN 'S' WHEN 'C' WHEN 'D' WHEN 'V' THEN 'Solteiro' THEN 'Casado' THEN 'Divorsiado' THEN 'Vivo'

ELSE 'Estado Civil inexistente' END FROM Cliente AS [Estado Civil]

-------------------------------------------------------------------

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

83

SELECT CASE WHEN Est_Civil = 'S' THEN 'Solteiro' WHEN Est_Civil = 'C' THEN 'Casado' WHEN Est_Civil = 'D' THEN 'Divorsiado' WHEN Est_Civil = 'V' THEN 'Vivo' ELSE END FROM Cliente 'Estado Civil inexistente' AS [Estado Civil]

-------------------------------------------------------------------

Note que temos duas opes de sintaxe para a utilizao da clusula CASE. A primeira escreve uma nica vez o nome da coluna Est_Civil e a segunda escreve-a vrias vezes, uma para cada WHEN.

H casos, como este, em que tanto faz voc utilizar a primeira como a segunda sintaxe, s que no caso da necessidade de se fazer comparaes um pouco mais complexas temos que utilizar a segunda sintaxe. Um exemplo disso o que mostramos abaixo:

SELECT Nome_Cli, CASE WHEN Renda_Cli <= 1000 THEN 'Crdito de 500.00'

WHEN Renda_Cli Between 1000 And 2000 THEN 'Crdito de 800.00'


Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

84

ELSE END FROM Cliente

'Credito Aprovado' AS Crdito

Como temos que comparar a Renda_Cli com uma faixa de valores, temos que optar pela segunda forma de se escrever este comando.

CASE COM ORDER BY


Podemos utilizar a clusula CASE tambm como uma opo no ORDER BY.

-- Para os clientes que tm como salrio um valor <= 1000 os dados so -apresentados ordenados pelo Nome_Cli de forma Decrescente -- Para os salrios que forem inferiores a 1000.00 os dados so -- apresentados ordenados de forma crescente tambm pelo Nome_Cli SELECT Cod_Cli,Nome_Cli,Sal_Cli FROM Cliente ORDER BY CASE Renda_Cli <= 1000.00 THEN Nome_Cli END DESC, CASE Renda_Cli < 1000.00 THEN Nome_Cli END ASC

-----------------------------------------------------------------------

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

85

-- Apresenta os dados ordenados pela coluna Nome_Cid quando o Sexo do --- cliente for 'F', caso contrrio apresenta os dados ordenados pelo -- Nome_Est

SELECT Cod_Cli,Nome_Cli,Sal_Cli FROM Cliente ORDER BY CASE Sexo_Cli WHEN 'F' THEN Nome_Cid ELSE Nome_Est END

CASE COM UPDATE


Muitas vezes precisamos fazer alteraes nos dados com base em condies, como no caso de aplicar um aumento na renda do cliente. Se o cliente for do sexo feminino o aumento devera ser de 20% e se for do sexo masculino dever ser de 10%.

UPDATE Cliente SET Renda_Cli = CASE Sexo_Cli = 'F' THEN Renda_Cli * 1.2 ELSE Renda_Cli * 1.1 END END

Abaixo temos uma variao do mesmo comando, apenas acrescentamos a clusula OUTPUT, para exibir os dados como eles eram antes da alterao.
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

86

UPDATE Cliente SET Renda_Cli = CASE Sexo_Cli = 'F' THEN Renda_Cli * 1.2 ELSE Renda_Cli * 1.1 END END OUTPUT DELETED.* WHERE Nome_Cid = 'So Paulo'

CASE COM HAVING


Tambm podemos restringir os dados de um agrupamento que sero apresentados utilizando a clusula CASE juntamente com HAVING.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

87

-- Exibe os valores das rendas dos clientes totalizando-as por Sexo_Cli -- Se o cliente for do sexo = 'F' apenas os dados com Renda_Cli > -- 500.00 sero considerados -- Se o cliente for do sexo = 'M' apenas os dados com Renda_Cli > -- 1000.00 sero considerados SELECT Sexo_Cli, Sum(Renda_Cli) FROM Cliente GROUP BY Sexo_Cli HAVING (Sum(CASE Sexo_Cli = 'F' THEN Renda_Cli END) > 500.00 OR Sum(CASE Sexo_Cli = 'M' THEN Renda_Cli END) > 1000.00)

-----------------------------------------------------------------------

A CLUSULA UNION
Muitas vezes precisamos exibir dados de vrias tabelas transformando-os em um nico conjunto de informao. Para tanto, temos alguns comandos que podem ser utilizados, dependendo obviamente, de como precisamos exibir a informao.

Para esta demonstrao execute o script abaixo:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

88

----------------------------------------------------------------------USE [50mnutos] ----------------------------------------------------------------------CREATE TABLE Aluno ( Cod_Alu int ,

Nome_Alu varchar(100), Ida_Alu ) tinyint

INSERT Aluno VALUES(1,'Maria',10) INSERT Aluno VALUES(2,'Rita',7) ----------------------------------------------------------------------CREATE TABLE Professor ( Cod_Prof int, Nome_Prof varchar(100), RG_Prof char(12) )

INSERT Professor VALUES(1,'Ricardo','155822')

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

89

INSERT Professor VALUES(2,'Roberto','152856') ----------------------------------------------------------------------CREATE TABLE Mestre ( Cod_Mestre int, Nome_Mestre varchar(100), DtCad_Mestre datetime, Sal_Mestre decimal(10,2) )

INSERT Mestre VALUES(1,'Paulo',Getdate(),10000.00) INSERT Mestre VALUES(2,'Paula',Getdate(),15000.00) -----------------------------------------------------------------------

UNION
Precisamos exibir os dados das tabelas Aluno, Professor e Mestre em um nico conjunto de resultado.

Utilizando a clusula UNION podemos conseguir atingir este objetivo. Observe:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

90

----------------------------------------------------------------------SELECT Cod_Alu Nome_Alu 'Aluno' Ida_Alu '' null FROM Aluno UNION SELECT Cod_Prof, Nome_Prof, 'Professor', 0, RG_Prof, null FROM Professor UNION SELECT Cod_Mestre, Nome_Mestre, 'Mestre', 0, AS Cdigo, AS Nome, AS Tipo, AS Idade, AS RG, AS Data

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

91

' ', DTCad_Mestre FROM Mestre -----------------------------------------------------------------------

Note que a utilizaao da cusula UNION tem algumas regras:

a) Todos os SELECTs utilizados devero apresentar a mesma quantidade de colunas e seus datatypes devem ser correspondentes entre si, ou seja, o tipo de dados da primeira coluna do primeiro SELECT tem que ser o mesmo tipo da primeira coluna do segundo SELECT e do terceiro. O tipo de dado da segunda coluna deve ser o mesmo para todas as segundas colunas de todos os SELECTs envolvidos no relatrio a ser gerado.

b) O Apelido para as colunas deve ser posto apenas no primeiro SELECT.

c) Cada SELECT pode ser escrito com JOIN, Subqueries, GROUP BY e WHERE.

d) Se desejarmos ordenar o conjunto de dados a clusula ORDER BY deve ser escrita no final, em ultimo lugar.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

92

UNION ALL
H uma diferena entre UNION e UNION ALL. Utilizando apenas a clusula UNION, se por acaso, houver os mesmos dados em mais de uma tabela, o SQL Server os apresentar apenas uma vez. Utilizando UNION ALL todas as linhas de dados sero exibidas, mesmo que haja repeties.

Valem para UNION ALL, as mesmas regras do UNION.

SELECT Cod_Alu Nome_Alu 'Aluno' Ida_Alu '' null FROM Aluno UNION ALL SELECT Cod_Prof, Nome_Prof, 'Professor', 0, RG_Prof,

AS Cdigo, AS Nome, AS Tipo, AS Idade, AS RG, AS Data

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

93

null FROM Professor UNION ALL SELECT Cod_Mestre, Nome_Mestre, 'Mestre', 0, ' ', DTCad_Mestre FROM Mestre

GROUPING SETS()
GROUPING SETS() uma clusula nova que pode ser substituir o UNION ALL, com uma performance melhor, nestes casos:

SELECT Count(Cod_Mestre) FROM Mestre UINON ALL SELECT Avg(DTCad_Mestre) FROM Mestre UNION ALL SELECT Sum(Sal_Mestre) FROM Mestre

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

94

-----------------------------------------------------------------------

Em vez de escrever tres queries nas mesma tabela como mostra o comando acima, utilize GROUPING SETS() como segue:

-- O SQL Server 2008 nos permite obter os mesmos dados acima -- com uma melhor performance, escrevendo a query utilizando -- as clusulas GROUPING SETS()

SELECT Count(Cod_Mestre), Avg(DTCad_Mestre),Sum(Sal_Mestre) FROM Mestre GROUP BY GROUPING SETS((Cod_Mestre),(DTCad_Mestre),(Sal_Mestre)())

INTERSECT E EXCEPT
INTERSECT a clusula que utilizamos para obter dados que fazem parte de duas tabelas ao mesmo tempo (interseco).

EXCEPT a clusula que utilizamos para ober dados que existem em uma tabela e no existem em outra.

Observe o udo das duas clusulas (INTERSECT e EXCEPT):

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

95

---------------------------------------------------------------------CREATE TABLE Mestre_Historico ( Cod_Mestre int, Nome_Mestre varchar(100), DtCad_Mestre datetime, Sal_Mestre decimal(10,2) )

INSERT Mestre_Historico VALUES(1,'Paulo',Getdate(),10000.00) INSERT Mestre_Historico VALUES(1000,'Ricardo',Getdate(),10000.00) ----------------------------------------------------------------------- INTERSECAO: O que tem igual nas duas tabelas -- Aparecer apenas os dados do Paulo, cujo cod_Mestre igual a 1 SELECT * FROM Mestre INSERSECT SELECT * FROM Mestre_Historico ---------------------------------------------------------------------

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

96

-- EXCEO: O que tem em uma tabela e no tem na outra -- Exibe apenas o que tem em Mestre e no tem no Mestre_Historico -- Aparecer s os dados do mestre de cdigo 2, chamado Paula. SELECT * FROM Mestre EXCEPT SELECT * FROM Mestre_Historico ---------------------------------------------------------------------- Exibe apenas o que tem em Mestre_Historico e no tem no Mestre -- Aparecer s os dados do mestre de cdigo 1000, chamado Ricardo. SELECT * FROM Mestre_Historico EXCEPT SELECT * FROM Mestre ---------------------------------------------------------------------

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

97

JOINS TRANSFORMANDO DADOS EM INFORMAO


Associar uma ou mais tabelas o mesmo que liga-las atravs de uma ou mais colunas que elas tenham em comum, com o objetivo de obter dados relacionado entre estas tabelas em questo. Existem algumas formas de associar dados dependendo do resultado que se deseja obter:

INNER JOIN ou JOIN - Apenas dados Relacionados o o o Natural-Join Equi-Join Self Join

OUTER JOIN Dados Relacionados e no Relacionados o o o Left Outer Join ou Left Join Right Outer Join ou Right Join Full Outer Join ou Full Join

CROSS JOIN Produto Cartesiano

Suponha que voce tenha uma tabela chamada Pai e uma tabela chamada Filho com a estrutura e dos dados apresentados logo abaixo:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

98

CREATE TABLE Pai ( Cod_Pai int identity not null Primary Key, Nome_Pai char(30) Idade_Pai tinyint ) not null, not null

CREATE TABLE Filho ( Cod_Filho int identity not null Primary Key, Cod_Pai int not null References Pai(Cod_Pai), not null, not null Check(Sexo_Filho IN (F,M))

Nome_Filho char(30) Sexo_Filho char(01) )

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

99

PAI Cod_Pai 1 2 3 Nome_Pai Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Fernando de Oliveira Leo 62 38 36 Idade_Pai

FILHO Cod_Filho 1 2 3 3 4 5 6 7 8 9 1 1 1 1 2 2 2 3 3 4 Cod_Pai Nome_Filho Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira dos Sandos Antonio dos Santos Neto Pedro Ferreira dos Santos Lucar Ribeiro Leo Helder Riberito Leo Mateus Ribeiro Leo F M F M M M M M M M Sexo_Filho

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

100

Voc poderia associar estas tabelas atravs da a Cod_Pai (coluna que comum s duas tabelas) para obter dados relacionados de diversas formas:

INNER JOIN
A clusula INNER JOIN tem como objetivo selecionar de duas ou mais tabelas apenas os dados relacionados entre todas elas. Um INNER JOIN poder ser: Um Natural Join ou Um Equi Join

INNER JOIN NATURAL JOIN

Suponha que voc precise obter o nome de todos os Pais e o nome e o sexo de todos os filhos que cada pai possui (observe os dados abaixo):

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

101

Nome do Pai
Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Fernando de Oliveira Leo Fernando de Oliveira Leo Fernando de Oliveira Leo

Nome do Filho
Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira dos Santos Antonio dos Santos Neto Pedro Ferreira dos Santos Lucas Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo F M F M M M M M M M

Sexo

Para conseguir esta resposta ser necessrio relacionar as duas tabelas. Note que estas duas tabelas se relacionam pela coluna Cod_Pai. Isto quer dizer que as duas tabelas tm a coluna Cod_Pai e que elas possuem os mesmos valores. Se voc observar tambm, esta coluna comum s duas tabelas, a chave primria da tabela Pai e a chave estrangeira na tabela Filho. Para obter os dados desejados execute o seguinte comando: SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Filho.Sexo_Filho as Sexo FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

102

IMPORTANTE: Observe que, para executar o comando acima, no necessrio que as tabelas tenham as constraints Primary Key e Foreign Key, basta que as colunas que relacionam as duas tabelas sejam do mesmo datatype. Para que a resposta que voc vai obter faa sentido para o seu sistema os dados tm que estar relacionados, ou seja, todos os filhos tm que ter um pai existente na tabela pai. Obviamente as constraints garantem que os dados obtidos como resposta so vlidos, porque elas no permitiro que sejam executadas operaes que provoquem inconsistncias nos mesmos. o EQUI JOIN

Este INNER JOIN abaixo, que retorna todas as linhas relacionadas de duas tabelas e apresenta todas as colunas das tabelas evolvidas no comando conhecido como Equi-Join porque apresentar, por exemplo, dados repetidos na coluna Cod_Pai (que existe nas duas tabelas).

SELECT * FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai Se voc selecionar no seu comando com INNER JOIN apenas colunas que no se repetem, este INNER JOIN ser um Natural-Join:

SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Filho.Sexo_Filho as Sexo FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

103

SELF JOIN

Self Join um Inner Join de uma tabela consigo mesma. Este tipo de join apresenta dados de um auto-relacionamento.

O auto-relacionamento acontece quando uma determinada chave estrangeira de uma tabela est relacionada com a chave primria da mesma tabela. Observe o caso da tabela funcionrio apresentada a seguir:

CREATE TABLE Funcionario ( Cod_Func int not null,

Nom_Func char(10) not null, Cod_Chefe int null,

Constraint PK_Func Primary Key(Cod_Func), Constraint FK_Func Foreign Key(Cod_Chefe) References (Cod_Func) )

Note que o comando acima coloca uma chave primria na coluna Cod_Func e a chave estrangeira, que colocada na coluna Cod_Chefe, faz referncia a coluna Cod_Func.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

104

A tabela Funcionrio armazena dados do Funcionrio e o seu Chefe, sendo que um chefe s poder ser chefe se for antes um funcionrio.

Se voc observar, a coluna Cod_Chefe aceita valores nulos, para que voc possa inserir funcionrios que no tenham chefe algum, ou que sejam seu prprio chefe. Veja a tabela com dados:

Cod_Func 1 2 3 4 5 6 7 8 9 10 Joo Matheus Lucas Pedro Thiago Jos Tnia Joana Rosana Maria

Nom_Func

Cod_Chefe NULL 1 1 2 2 2 1 3 3 4

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

105

Voc oportunidade, em tpicos anteriores, de aprender a colocar Alias na colunas das tabelas em um Select para obter dados com uma visualizao meis amigvel, ou seja para poder visualizar as colunas com um ttulo diferente do armazenado na tabela. Para fazer o Self Join voc precisa tambm saber escrever o alias de tabela. Isto bem simples:

SELECT F.Cod_Func, F.Nom_Func, F.Cod_Chefe FROM Funcionario F

Muito embora no seja necessrio utilizar o alias de tabela no Select apresentado acima, a letra F o alias de tabela.

Para obter como resposta o nome de todos os funcionrios e de seus chefes voce dever escrever o comando abaixo, que associa a tabela Funcionrio com ela mesma:

SELECT A.Nom_Func as Chefe, B.Nom_Func as Funcionario FROM Funcionario A inner join Funcionario B ON A.Cod_Func = B.Cod_Chefe ORDER BY 1

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

106

Note que o self join escrito acima associa a tabela Funcionrio com ela mesma, utilizando para isso as letras A e B para fazer o alias de tabela. O join associa as duas tabelas A e B atraves das colunas Cod_Func e Cod_Chefe.

Note tambm que alm de utilizar o alias de tabela foi utilizado alias de coluna para facilitar a compreeno dos dados.

Ao executar o comando anterior voc obtm a seguinte resposta:

Chefe Joo Joo Joo Lucas Lucas Matheus Matheus Matheus

Funcionrio Matheus Lucas Tania Joana Rosana Jos Pedro Thiago

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

107

LEFT JOIN
Utilizando novamente o exemplo do relacionamento entre as tabela Pai e Filho, observe que na tabela pai agora existe um pai para o qual no foi registrado nenhum filho na tabela Filho. Esta situao no representa um erro, porque necessrio registrar primeiro o pai para depois inserir seus filhos. Neste caso, suponha que voc inseriu o Pai cujo cdigo o nmero 4 e que ainda no colocou nenhum filho para ele. Observe a demonstrao abaixo: PAI Cod_Pai 1 2 3 4 Nome_Pai Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Fernando de Oliveira Leo Jairo de Oliveira Leo

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

108

FILHO Cod_Filho 1 2 3 3 4 5 6 7 8 9 1 1 1 1 2 2 2 3 3 3 Cod_Pai Nome_Filho Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira dos Santos Antonio dos Santos Neto Pedro Ferreira dos Santos Lucas Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo F M F M M M M M M M Sexo_Filho

Para que voc possa exibir os dados de todos os pais relacionando estes dados com os respectivos filhos, mostrando tambm os dados dos pais que ainda esto sem filhos registrados, escreva o seguinte comando: SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Filho.Sexo_Filho as Sexo FROM Pai LEFT OUTER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

109

A clusula LEFT est sendo utilizada para mostrar todos os dados da tabela escrita do lado esquerdo do join. O conjunto resposta obtido com a execuo do comando acima este:

Nome do Pai
Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Fernando de Oliveira Leo Fernando de Oliveira Leo Fernando de Oliveira Leo

Nome do Filho
Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira Antonio dos Santos Neto Pedro Ferreira dos Santos Lucar Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo F M F M M M M M M M

Sexo

Note que o SQL Server relacionou os dados como fez no caso do INNER JOIN, mas no caso do LEFT JOIN especificamente, mostrou tambm os dados da tabela Pai (tabela que foi escrita do lado esquerdo das palavras LEFT OUTER JOIN) que no se relacionaram com nenhum filho. Se voc precisasse obter como resposta apenas os dados dos pais para os quais voc ainda no inseriu nenhum filho bastaria acrescentar ao comando a clusula WHERE como segue:

SELECT Pai.* FROM Pai LEFT OUTER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai WHERE Filho.Nome_Filho IS NULL
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

110

RIGHT JOIN

Em uma outra situao, suponha que por algum motivo, foi necessrio inserir alguns filhos na tabela Filho, para um pai que no existe na tabela Pai. Ento, para fazer isso, voc desligou a constraint de chave estrangeira, inseriu os dados inconsistentes e religou a chave estrangeiras dizendo para o SQL Server no checar dados j existentes. Suponha, ento, que seus dados ficaram desta forma: PAI Cod_Pai 1 2 3 4 Nome_Pai Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Fernando de Oliveira Leo Jairo de Oliveira Leo

FILHO Cod_Filho 1 2 3 3 4 5 1 1 1 1 2 2 Cod_Pai Nome_Filho Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira dos Santos Antonio dos Santos Neto F M F M M M Sexo_Filho

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

111

6 7 8 9 10 11 12

2 3 3 3 1000 1000 1000

Pedro Ferreira dos Santos Lucas Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo Sandra Rosa Madalena Margarida Paula Regina Ana Maria Cristina

M M M M F F F

Os trs ltimos filhos pertencem a um pai cujo cdigo o nmero 1000 e este pai no existe na tabela Pai. Se voc precisasse obter como resposta os dados dos filhos e seus pais, mostrando inclusive os filhos rfos, voc precisaria escrever o seguinte comando: SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Filho.Sexo_Filho as Sexo FROM Pai RIGHT OUTER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

112

Nome do Pai
Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Fernando de Oliveira Leo Fernando de Oliveira Leo Fernando de Oliveira Leo Null Null

Nome do Filho
Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira Antonio dos Santos Neto Pedro Ferreira dos Santos Lucar Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo Sandra Rosa Madalena Margarida Paula Regina F M F M M M M M M M F F

Sexo

Null

Ana Maria Cristina

Se voc precisasse obter como resposta apenas os dados dos filhos para os quais voc no inseriu nenhum pai, voc poderia escrever o comando assim:

SELECT Filho.* FROM Pai RIGHT OUTER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai WHERE Pai.Cod_Pai IS NULL

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

113

FULL JOIN
possvel que voc precise ler, em apenas uma resposta, todos os dados relacionados e no relacionados. Suponha que voc precise ento dos seguintes dados: Nome do Pai
Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Agnaldo Diogo dos Santos Fernando de Oliveira Leo Fernando de Oliveira Leo Fernando de Oliveira Leo Jairo de Oliveira Leo Null Null Null

Nome do Filho
Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira Antonio dos Santos Neto Pedro Ferreira dos Santos Lucar Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo NULL Sandra Rosa Madalena Margarida Paula Regina Ana Maria Cristina F M F M M M M M M M

Sexo

NULL F F F

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

114

O comando que dever ser escrito para que voc receba estes dados como resposta esse: SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Filho.Sexo_Filho as Sexo FROM Pai FULL OUTER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai Se voc precisasse obter como resposta apenas os dados no relacionados voc poderia escrever o comando assim: SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Filho.Sexo_Filho as Sexo FROM Pai FULL OUTER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai WHERE Pai.Cod_Pai IS NULL OR Filho.Cod_Pai IS NULL

CROSS JOIN
o produto cartesiano. O Cross Join relaciona todas as linhas da tabela A com todas as linhas da tabela B. Observe o exemplo a seguir:

Material Cod_Mat 1 2 3 4 Caderno Lpis Borracha Caneta Mome_Mat

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

115

Pedido Num_Ped 1 2 Data_Ped 24/06/2009 06/08/2009

De acordo com os dados acima, execute estes comandos: SELECT Pedido.Num_Ped, Material.Nome_Mat FROM Pedido CROSS JOIN Material Os dados que voc obtm como resposta so os seguintes: Num_Ped 1 1 1 1 2 2 2 2 Cod_Mat Caderno Lpis Borracha Caneta Caderno Lpis Borracha Caneta

Em todos os pedidos foram vendidos uma determinada quantidade de todos os materiais.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

116

JOIN COM MAIS DE DUAS TABELAS


Agora voc deve supor que no seu sistema existam estas trs tabelas:

PAI Cod_Pai 1 2 3 4 Nome_Pai Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Fernando de Oliveira Leo Jairo de Oliveira Leo

FILHO Cod_Filho 1 2 3 3 4 5 6 1 1 1 1 2 2 2 Cod_Pai Nome_Filho Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferreira dos Santos Antonio dos Santos Neto Pedro Ferreira dos Santos F M F M M M M Sexo_Filho

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

117

7 8 9 10 11 12

3 3 3 1000 1000 1000

Lucas Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo Sandra Rosa Madalena Margarida Paula Regina Ana Maria Cristina

M M M F F F

Num_Lanc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

NOTAS Cod_Filho 1 1 1 2 2 3 3 4 4 5 5 6 7 7 8 8 9

Nota_Filho 10,00 9,00 10,00 8,00 7,00 5,00 10,00 9.5 9.0 10.0 7.8 9.0 7.5 6.7 8.8 9.0 10.0

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

118

SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Nota.Nota_Filho as [Nota do Filho] FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai INNER JOIN Nota ON Filho.Cod_Filho = Nota.Cod_Filho Para processar este comando, o SQL Server faz o Join entre a tabela Pai e Filho, e deste conjunto resultante faz o join com a tabela Nota. SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Nota.Nota_Filho as [Nota do Filho] FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai LEFT JOIN Nota ON Filho.Cod_Filho = Nota.Cod_Filho O comando acima mostra todos os pais e seus filhos e as notas destes filhos, mostra inclusive os filhos sem nota. SELECT Pai.Nome_Pai as [Nome do Pai], Filho.Nome_Filho as [Nome do Filho], Nota.Nota_Filho as [Nota do Filho] FROM Pai LEFT JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai LEFT JOIN Nota ON Filho.Cod_Filho = Nota.Cod_Filho O comando acima mostra todos os dados relacionados, pai com filho e filho com nota, mostra tambm os pais com filhos e filhos sem nota e os pais que ainda esto sem filhos cadastrados.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

119

EVITANDO AMBIGUIDADE
Ambigidade um tipo de erro que acontece quando voc executa um Join de duas ou mais tabelas que exibe colunas que tenham o mesmo nome nas duas ou mais tabelas envolvidas no comando. Por exemplo, no join escrito logo abaixo, que associa a tabela pai e a tabela filho, aparece a coluna Cod_Pai, que existe tanto na tabela Pai quanto na tabela Filho. Neste caso, o SQL Server no consegui definir de qual das duas tabelas ele deve obter os dados da coluna Cod_Pai e exibe o erro apresentado aps a exibio do comando: SELECT Cod_Pai, Cod_Filho, Nome_Pai, Nome_Filho FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai Server: Msg 209, Level 16, State 1, Line 1 Ambiguous column name 'Cod_Pai'. Para evitar a ambigidade, basta que voc defina para o SQL Server de qual das duas tabelas ele dever obter os dados: SELECT Pai.Cod_Pai, Cod_Filho, Nome_Pai, Nome_Filho FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai Desta forma no ocorrer mais o erro de nmero 209. Como voc deve ter percebido, necessrio indicar a tabela de onde o SQL Server deve obter os dados, apenas quando nas tabelas envolvidas no Join existirem colunas com nomes em comum e quando voc precisar exibir justamente o contedo destas colunas. Caso contrrio no ser necessrio especificar de qual tabela os dados devero ser obtidos. Se voc sempre especificar o nome da tabela antes do nome da coluna em todos os joins que escrever nunca cometer um erro de ambigidade.
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

120

SELECT Pai.Cod_Pai, Filho.Cod_Filho, Pai.Nome_Pai, Filho.Nome_Filho FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

UPDATE COM JOIN


Muitas vezes ser necessrio alterar os dados de uma tabela com base na existncia ou no de dados relacionados em outra tabela. Por exemplo, voc poderia desejar aumentar a Idade para mais um ano de todos os pais que possuem filhos. Para realizar esta tarefa, voc dever escrever um Update com um Join: UPDATE Pai SET Idade_Pai = Idade_Pai + 1 FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai Se voc tiver dificuldade em escrever este comando, escreva primeiro o update que deixa todos os pais um anos mais velhos, depois escreva um comando select fazendo um join entre a tabela pai e filho: UPDATE Pai SET Idade_Pai = Idade_Pai + 1 SELECT * FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

121

Em seguida, retire a linha Select * do comando escrito acima e junte o Update inteiro com a clausula From que restou do segundo comando: UPDATE Pai SET Idade_Pai = Idade_Pai + 1 FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai Pronto, aqui est o Update com Join, que deixa um ano mais velhos apenas os pais que j tem pelo menos um filho correspondente na tabela Filho. Voc poder tambm escrever Updates com Joins que associam mais de duas tabelas, conforma seja necessrio.

DELETE COM JOIN


Suponha que voc precisasse excluir os filhos que no receberam um respectivo pai na tabela Pai. Para tanto, siga o mesmo raciocnio anterior. Escreva o comando delete, escreva o select com o join, e depois retire a linha select do join, junte o update com a clusula from e apague os filhos rfos. DELETE Filho

SELECT * FROM Pai RIGHT JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai WHERE Pai.Cod_Pai IS NULL

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

122

Execute este comando aps retirar a linha do Select: DELETE Filho FROM Pai RIGHT JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai WHERE Pai.Cod_Pai IS NULL

JOINS ENTRE TABELAS QUE POSSUEM CHAVES COMPOSTAS


Suponha que voc tenha duas tabelas como as que seguem, onde a primeira tem uma chave primaria composta de duas colunas e a segunda, que se relaciona com a primeira, tem uma chave estrangeira composta das mesmas colunas: CREATE TABLE Tab_A ( ColunaA1 datatype Not Null, ColunaA2 datatype Not Null, ColunaA3 datatype Not Null, Constraint PK_TabA Primary Key(ColunaA1,.ColunaA2) )

CREATE TABLE Tab_B ( ColunaB1 datatype Not Null Primary Key, ColunaA1 datatype Not Null, ColunaA2 datatype Not Null, Constraint FK_TabB Foreign Key(ColunaA1,ColunaA2) References Tab_A (ColunaA1,ColunaA2) ) Para obter dados relacionados entre estas duas tabelas o joins dever ser escrito desta forma:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

123

SELECT Tab_A.ColunaA1, Tab_A.ColunaA2, Tab_A.ColunaA3, Tab_B.ColunaB1 FROM Tab_A INNER JOIN Tab_B ON Tab_A.ColunaA1 = Tab_B.ColunaA1 AND Tab_A.ColunaA2 = Tab_B.ColunaA2

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

124

SUBQUERY
Neste assunto sero utilizadas as tabelas Pai e Filho (expostas logo abaixo) nas explicaes e dempostraes.

CREATE TABLE Pai ( Cod_Pai int identity not null Primary Key, Nome_Pai char(30) Idade_Pai tinyint ) not null, not null

CREATE TABLE Filho ( Cod_Filho int identity not null Primary Key, Cod_Pai int not null References Pai(Cod_Pai), not null, not null Check(Sexo_Filho IN (F,M))

Nome_Filho char(30) Sexo_Filho char(01) )

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

125

PAI Cod_Pai 1 2 3 4 Nome_Pai Daniel de Souza Leo Sobrinho Agnaldo Diogo dos Santos Fernando de Oliveira Leo Jairo de oliveira Leo Idade_Pai 69 43 42 39

FILHO Cod_Filho 1 2 3 3 4 5 6 7 8 9 1 1 1 1 2 2 2 3 3 3 Cod_Pai Nome_Filho Renata de Oliveira Leo Fernando de Oliveira Leo Roberta de Oliveira Leo Jairo de Oliveira Leo Bruno Ferraira dos Santos Antonio dos Santos Neto Pedro Ferreira dos Santos Lucas Ribeiro Leo Helder Ribeiro Leo Mateus Ribeiro Leo F M F M M M M M M M Sexo_Filho

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

126

As subqueries permitem que voc obtenha dados de uma tabela com base na existncia destes dados em outra ou outras tabelas. Por exemplo, suponha que voc precisasse obter da tabela Pai todos os dados do pai mais velho. Para tanto voc vai precisar utilizar a funo de totalizao MAX() e uma subquery:

SELECT * FROM Pai WHERE Idade_Pai = (SELECT Max(Idade_Pai) FROM Pai)

O segundo select do comando acima chamado de subquery e o primeiro select chamado de outer query ou apenas de query. O SQL Server resolve a subquery obtendo o valor maior da coluna Idade_Pai e em seguida obtem todas as colunas da tabela Pai onde a coluna Idade_Pai igual a esse valor obtido pela subquery.

A resposta obtida :

PAI Cod_Pai 1 Nome_Pai Daniel de Souza Leo Sobrinho 69 Idade_Pai

O comando acima poderia ser lido da seguinte maneira: Selecione todos as colunas da tabela Pai onde a idade do pai IGUAL { maior idade obtida com a subquery.
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

127

A mesma resposta poderia ser obtida se voc introduzisse a subquery com o operador IN:

SELECT * FROM Pai WHERE Idade_Pai IN (SELECT Max(Idade_Pai) FROM Pai)

O comando acima poderia ser lido da seguinte maneira: Selecione todos as colunas da tabela Pai onde a idade do pai EST no conjunto de dados retornado pela subquery.

Para obter este tipo de informao, ou seja, dados que sejam do maior ou do menor valor, s possvel quando se utiliza uma subquery.

SUBQUERY INTRODUZIDA COM O PERADOR DE COMPARAO


As subqueries introduzidas com os operadores de comparao devem retornar sempre apenas um nico valor. Por exemplo, a subquery que obtm o maior valor da coluna Idade_Pai, retorna apenas um valor o maior.

Voc poderia utilizar outros sinais de comparao, como por exemplo:

a) Obtenha todos os dados dos pais sem mostrar o Pai mais velho:

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

128

SELECT * FROM Pai WHERE Idade_Pai <> (SELECT Max(Idade_Pai) FROM Pai)

SELECT * FROM Pai WHERE Idade_Pai < (SELECT Max(Idade_Pai) FROM Pai)

b) Obtenha todos os dados do pai mais novo:

SELECT * FROM Pai WHERE Idade_Pai = (SELECT Min(Idade_Pai) FROM Pai)

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

129

SUBQUERY INTRODUZIDA COM IN OU NOT IN


As subqueries introduzidas com os operadores IN ou NOT IN devem retornar sempre valores de apenas uma coluna, mas podero retornar mais de uma linha como resposta.

Por exemplo, suponha que voc precisasse obter da tabela Pai todas as colunas apenas dos pais que possuem um ou mais filhos registrados na tabela Filho. Para tanto voc poderia escrever os seguintes comandos:

SELECT * FROM Pai WHERE Cod_Pai IN (SELECT Cod_Pai FROM Filho)

Suponha que voc precisasse obter da tabela Pai todas as colunas apenas dos pais que ainda NO possuem filhos registrados na tabela Filho. Para tanto voc poderia escrever os seguintes comandos:

SELECT * FROM Pai WHERE Cod_Pai NOT IN (SELECT Cod_Pai FROM Filho)

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

130

O resultado obtido com o uso das subqueries podem ser obtidos pelos joins, pois os joins apresentam melhor performance do que as subqueries:

SELECT * FROM Pai WHERE Cod_Pai IN (SELECT Cod_Pai FROM Filho)

Substitua o comando escrito acima por:

SELECT DISTINCT Pai.* FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

SELECT * FROM Pai WHERE Cod_Pai NOT IN (SELECT Cod_Pai FROM Filho)

Substitua o comando escrito acima por: SELECT Pai.* FROM Pai LEFT JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai WHERE Filho.Cod_Pai IS NULL
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

131

Subquery Introduzida com EXISTS e NOT EXISTS

Voc poder utilizar os operadores EXISTS e NOT EXISTS para obter, por exemplo dados relacionados entre as tabelas pai e Filho. Para obter todos os pais que possui pelo menos um filho registrado na tabela Filho voc poderia escrever o seguinte comando:

SELECT * FROM Pai WHERE EXISTS (SELECT Cod_Pai FROM Filho WHERE Filho.Cod_Pai = Pai.Cod_Pai)

Para obter os dados da tabela Pai, mas apenas dos pais que no possuem um filho correspondente na tabela Filho, voc poderia escrever o seguinte comando:

SELECT * FROM Pai WHERE NOT EXISTS (SELECT Cod_Pai FROM Filho WHERE Filho.Cod_Pai = Pai.Cod_Pai)

Observe que nas subqueries acima, utiliza-se na clusula Where a tabela Pai, que no foi citada na clusula From destas mesmas subqueries. A tabela Pai da clusula Where das subqueries est se relacionando com a Query. Portanto, para cada linha selecionada da tabela Pai pela query, o SQL Server tem que executar uma vez a subquery que obtem dados da tabela Filho. Assim, se houver na tabela Pai, 10 Pais registrados, o SQL Server executar 10 vezes a subquery correspondente.
Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

132

Justamente porque estas subqueries esto amarradas com a query, elas so chamadas de Subqueries Correlacionadas.

As Subqueries Correlacionadas normalmente consomem muitos recursos do sistema para serem processadas, portanto sempre d preferencia para obter seus dados escrevendo joins que tm um melhor processamento.

interessante que voc conhea as subqueries para poder interpret-las quando necessrio.

Voc poder se deparar com subqueries que formam uma coluna resposta de um select. Por exemplo, a subquery abaixo apresenta todos os dados da tabela Pai e apresenta tambm uma coluna a mais (que no existe fisicamente na tabela Pai) que mostra a quantidade de filhos que cada pai possui. Observe:

SELECT *, (SELECT Count(Cod_Pai) FROM Filho WHERE Filho.Cod_Pai = Pai.Cod_Pai) AS Qtd_Filho FROM Pai

Note que a subquery acima se correlaciona com a query atravs da tabela Pai.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

133

SUBSTITUINDO SUBQUERIES
1 Para selecionar todos os pais que possuem filhos existem tres possibilidades. A lttima apresentar melhor performance.

/* Subquey correlacionada*/ SELECT * FROM Pai WHERE EXISTS (SELECT Cod_Pai FROM Filho WHERE Filho.Cod_Pai = Pai.Cod_Pai)

/* Subquery no correlacionada*/ SELECT * FROM Pai WHERE Cod_Pai IN (SELECT Cod_Pai FROM Filho)

/* Inner Join*/ SELECT DISTINCT Pai.* FROM Pai INNER JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

134

2 Para selecionar todos os pais que no possuem filhos existem tres possibilidades. A lttima apresentar melhor performance.

/* Subquey correlacionada*/ SELECT * FROM Pai WHERE NOT EXISTS (SELECT Cod_Pai FROM Filho WHERE Filho.Cod_Pai = Pai.Cod_Pai)

/* Subquery no correlacionada*/ SELECT * FROM Pai WHERE Cod_Pai NOT IN (SELECT Cod_Pai FROM Filho)

/* Left Join e IS NULL*/ SELECT Pai.* FROM Pai LEFT JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai WHERE Filho.Cod_Pai IS NULL

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

135

3 Para apresentar todos os dados da tabela Pai e a quantidade de filhos que cada pai possui existem duas possibilidade, a ltima oferece melhor performance:

/*Subquery Correlacionada*/ SELECT *, (SELECT Count(Cod_Pai) FROM Filho WHERE Filho.Cod_Pai = Pai.Cod_Pai) AS Qtd_Filho FROM Pai

/* Left Join com Group By e a funo de totalizao Count() */ SELECT Pai.Cod_Pai,Pai.Nome_Pai,Count(Filho.Cod_Pai) AS Qtd_Pai FROM Pai LEFT JOIN Filho ON Pai.Cod_Pai = Filho.Cod_Pai GROUP BY Pai.Cod_Pai,Pai.Nome_Pai

OBS: O ganho de performance s perceptvel quando as tabelas possuem uma quantidade razovel de dados.

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

136

SUBQUERIES ANINHADAS
As subqueries aninhadas so formadas de vrios comandos SELECT. Voc ter uma query e duas ou mais subqueries. Observe abaixo as tabelas utilizadas como exemplo: CLIENTE Nome_Cli Joo Gaucho Daniel Leo Jairo Gato Roberta Zapata Helena Leito

Cod_Cli 1 2 3 4 5

Renda_Cli 5000,00 6000,00 3500,00 5500,00 2500,00

CNJUGE Cod_Cli 1 2 Nome_Conj Maria Souza Gaucho Helena Leo Renda_Conj 2500,00 3030,00 Idade_Conj 20 25

PEDIDO Num_Ped 1 2 1 3 Cod_Cli Data_Ped 01/05/02 02/06/02 Val_Ped 2800,00 3055.20

Cod_Prod 1 2 3

PRODUTO Nome_Prod Qtd_Prod Caderno 100 Lpis 200 Borracha 500

Val_Prod 15.56 1.52 0.58

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

137

Num_Ped 1 1 2 2 2 1 2 1 2 3

ITENS Cod_Prod 50 10 30 10 5

Qtd_Prod

Para obter, por exemplo, os dados de todos os cliente solteiros que j fizeram pelo menos um pedido, voc poderia escrever o seguinte somando:

SELECT * FROM Cliente WHERE Cod_Cli NOT IN(SELECT Cod_Cli FROM Conjuge) AND Cod_Cli IN(SELECT Cod_Cli FROM Pedido)

Segue abaixo a resposta obtida:

Cod_Cli 3

CLIENTE Nome_Cli Jairo Gato

Renda_Cli 3500,00

Para obter os dados de todos os clientes que compraram, por exemplo o produto 1, escreva o seguinte comando: SELECT * FROM Cliente WHERE Cod_Cli IN (SELECT Cod_Cli FROM Pedido WHERE Num_Ped IN (SELECT Num_Ped FROM Itens WHERE Cod_Prod = 1))

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

138

UPDATE COM SUBQUERY


Voc poder alterar dados de uma tabela com base na existncia de dados em outras tabelas utilizando subqueries. Por exemplo, voc poderia alterar a renda dos clientes que compraram o produto de cdigo 1. Observe: UPDATE Cliente SET Renda_Cli = Renda_Cli * 1.1 WHERE Cod_Cli IN (SELECT Cod_Cli FROM Pedido WHERE Num_Ped IN (SELECT Num_Ped FROM Itens WHERE Cod_Prod = 1))

DELETE COM SUBQUERY


Voc poder excluir dados de uma tabela com base na existncia de dados em outras tabelas utilizando subqueries. Por exemplo, voc poderia excluir da tabela produto todos os produtos que nunca foram vendidos: DELETE Produto WHERE Cod_Prod NOT IN (SELECT Cod_Prod FROM Itens)

Rua Domingos de Moraes, 770, bloco 2, conjunto 9 Vila Mariana - So Paulo - SP 11 2361 3050 | 11 2361 4050
contato@50minutos.com.br

Das könnte Ihnen auch gefallen