Criar Web, manuais e recursos para desenvolvimento web
Manuais
Programas
FAQS
Diretório
Comunidade
  Inicio > Manuais > Tutorial de SQL
SEÇÕES
Manuais relacionados
+Tutorial de SQL
Categorias
+Linguagem SQL

Índice do Manual Tutorial de SQL
+ O que é SQL
+ Tipos de campos
+ Adicionar um novo registro
+ Apagar um registro
+ Atualizar um registro
+ Seleção de tabelas I
+ Seleção de tabelas II
+ Seleção de tabelas III
+ Seleção de tabelas IV
+ Aproveite seu banco de dados
+ Tabelas temporárias no Sql Server
+ Adquirindo informações do Usuário com a classe System
+ Alguns truques práticos
+ Criação de tabelas
+ SQL e Programação de Banco de Dados
+ Funções para buscas com datas em Access
+ Função em SQL para o cálculo de dias de trabalho
+ SQL com Oracle
+ SQL com Oracle. Operadores
+ Sub-consultas SQL
+ Funções SQL
+ Agrupamento e combinação de elementos com SQL
+ Manipulação de dados com SQL
+ Chaves primárias com SQL com Oracle
+ Definição de chaves para tabelas e restrições
+ Supressão e modificação de tabelas com SQL
+ Gerenciamento de vistas em SQL
+ Usuários em Oracle
+ Gerenciamento em Oracle com SQL
+ Otimizar consultas SQL
+ Consultas de seleção
+ Critérios de seleção em SQL
+ Como exibir informações com múltiplas instruções SQL
+ Critérios de seleção em SQL II
+ Consultas de ação
+ Tipos de dados SQL
+ Subconsultas em SQL
+ Consultas SQL de União Internas
+ Estruturas das tabelas em SQL
+ Cursores em SQL
+ Referências Cruzadas em SQL
+ Introdução a freetext e contains em SQL-Server
+ Acesso ao banco de dados externos
+ Consultas com parâmetros e omissão de permissões
+ Procedures e busca de registros duplicados em SQL
+ A função datepart() em Access
+ Emular um Cursor SQL com um Loop
+ Tipos de instruções SQL e seus componentes sintáticos

Descrição dos capítulos

Parceiros
- CSS para Web Design
- S.O.S Designers
- Slackware-Brasil
- Crie seu Web site
- Oficina da Net


Consultas SQL de União Internas

Detalhamos estas consultas da linguagem SQL tão importantes para o bom desenvolvimento de um banco de dados.


Consultas de Combinação entre tabelas

As vinculações entre tabelas se realizam mediante a cláusula INNER que combina registros de duas tabelas sempre que tiver concordância de valores em um campo comum. Sua sintaxe é:

SELECT campos FROM tb1 INNER JOIN tb2 ON
tb1.campo1 comp tb2.campo2


Onde:

tb1, tb2São os nomes das tabelas desde as que se combinam os registros.
campo1, campo2São os nomes dos campos que se combinam. Se não são numéricos, os campos devem ser do mesmo tipo de dados e conter o mesmo tipo de dados, porém não tem que ter o mesmo nome.
compÉ qualquer operador de comparação relacional: =, <,<>, <=, =>, ó >.

Pode-se utilizar uma operação INNER JOIN em qualquer cláusula FROM. Isto cria uma combinação por equivalência, conhecida também como união interna. As combinações equivalentes são as mais comuns; estas combinam os registros de duas tabelas sempre que tiver concordância de valores em um campo comum a ambas tabelas. Pode-se utilizar INNER JOIN com as tabelas Departamentos e Empregados para selecionar todos os empregados de cada departamento. Do contrário, para selecionar todos os departamentos (inclusive se algum deles não tiver nenhum empregado atribuído) se emprega LEFT JOIN ou todos os empregados (inclusive se algum não estiver atribuído a nenhum departamento), neste caso RIGHT JOIN.

Se se tenta combinar campos que contenham dados Memo ou Objeto OLE, se produz um erro. Podem-se combinar dois campos numéricos quaisquer, inclusive se são de diferentes tipos de dados. Por exemplo, pode combinar um campo Numérico para o que a propriedade Size de seu objeto Field está estabelecida como Inteiro, e um campo Contador.

O exemplo seguinte mostra como poderia combinar as tabelas Categorias e Produtos baseando-se no campo IDCategoria:

SELECT
    NomeCategoria, NomeProduto
FROM
   Categorias
INNER JOIN
   Produtos
ON
    Categorias.IDCategoria = Produtos.IDCategoria


No exemplo anterior, IDCategoria é o campo combinado, porém não está incluído na saída da consulta já que não está incluído na instrução SELECT. Para incluir o campo combinado, incluir o nome do campo na instrução SELECT, neste caso, Categorias.IDCategoria.

Também se pode linkar várias cláusulas ON em uma instrução JOIN, utilizando a seguinte sintaxe:

SELECT campos FROM tabela1 INNER JOIN tabela2
ON (tb1.campo1 comp tb2.campo1 AND ON tb1.campo2 comp tb2.campo2)
OR ON (tb1.campo3 comp tb2.campo3)


Também pode aninhar instruções JOIN utilizando a seguinte sintaxe:

SELECT campos FROM tb1 INNER JOIN (tb2 INNER JOIN [( ]tb3
[INNER JOIN [( ]tablax [INNER JOIN ...)]
ON tb3.campo3 comp tbx.campox)]
ON tb2.campo2 comp tb3.campo3)
ON tb1.campo1 comp tb2.campo2


Um LEFT JOIN ou um RIGHT JOIN pode se aninhar dentro de um INNER JOIN, porém um INNER JOIN não pode se aninhar dentro de um LEFT JOIN ou um RIGHT JOIN.

Exemplo:

SELECT DISTINCT
   Sum(PrecoUnitario * Quantidade) AS Sales,
(Nome + ' ' + Sobrenome) AS Name
FROM
    Empregados
INNER JOIN(
    Pedidos
INNER JOIN
   DetalhesPedidos
   ON
   Pedidos.IdPedido = DetalhesPedidos.IdPedido)
    ON
    Empregados.IdEmpregado = Pedidos.IdEmpregado
GROUP BY
   Nome + ' ' + Sobrenome

(Cria duas combinações equivalentes: uma entre as tabelas Detalhes de pedidos e Pedidos, e a outra entre as tabelas Pedidos e Empregados. Isto é necessário já que a tabela Empregados não contem dados de vendas e a tabela Detalhes de pedidos não contem dados dos empregados. A consulta produz uma lista de empregados e suas vendas totais.)

Se empregarmos a cláusula INNER na consulta se selecionarão só aqueles registros da tabela da que tivermos escrito à esquerda de INNER JOIN que contenham ao menos um registro da tabela que tivermos escrito à direita. Para solucionar isto temos duas cláusulas que substituem a palavra-chave INNER, estas cláusulas são LEFT e RIGHT. LEFT toma todos os registros da tabela da esquerda embora não tenha nenhum registro na tabela da esquerda. RIGHT realiza a mesma operação, porém ao contrário, toma todos os registros da tabela da direita embora não tenha nenhum registro na tabela da esquerda.

A sintaxe exposta anteriormente pertence a ACCESS, onde todas as sentenças com a sintaxe funcionam corretamente. Os manuais de SQL-SERVER dizem que esta sintaxe é incorreta e que há que adicionar a palavra reservada OUTER: LEFT OUTER JOIN e RIGHT OUTER JOIN. Na prática funciona corretamente de uma forma ou de outra.

Não obstante, os INNER JOIN ORACLE não é capaz de interpretá-los, mas existe uma sintaxe em formato ANSI para os INNER JOIN que funcionam em todos os sistemas. Tomando como referência a seguinte sentença:

SELECT
   Faturas.*,
   Alvaras.*
FROM
   Faturas
INNER JOIN
   Alvaras
ON
   Faturas.IdAlvara = Alvaras.IdAlvara
WHERE
   Faturas.IdCliente = 325

A transformação desta sentença a formato ANSI seria a seguinte:

SELECT
Faturas.*,
Alvaras.*
FROM
Faturas, Alvaras
WHERE
Faturas.IdAlvara = Alvaras.IdAlvara
AND
Faturas.IdCliente = 325


Como se pode observar as mudanças realizadas foram as seguintes:

  1. Todas as tabelas que intervêm na consulta se especificam na cláusula FROM.
  2. As condições que vinculam às tabelas se especificam na cláusula WHERE e se vinculam mediante o operador lógico AND.

Referente aos OUTER JOIN, não funcionam em ORACLE e ademais conheço uma sintaxe que funciona nos três sistemas. A sintaxe em ORACLE é igual à sentença anterior, porém adicionando os caracteres (+) atrás do nome da tabela na qual desejamos aceitar valores nulos, isto equivale a um LEFT JOIN:

SELECT
   Faturas.*,
    Alvaras.*
FROM
   Faturas, Alvaras
WHERE
   Faturas.IdAlvara = Alvaras.IdAlvara (+)
   AND
   Faturas.IdCliente = 325


E isto a um RIGHT JOIN:

SELECT
   Faturas.*,
    Alvaras.*
FROM
   Faturas, Alvaras
WHERE
   Faturas.IdAlvara (+) = Alvaras.IdAlvara
   AND
   Faturas.IdCliente = 325


Em SQL-SERVER se pode utilizar uma sintaxe parecida, neste caso não se utiliza os caracteres (+), e sim os caracteres =* para o LEFT JOIN e *= para o RIGHT JOIN.

Consultas de Auto-combinação

A auto-combinação se utiliza para unir uma tabela consigo mesma, comparando valores de duas colunas com o mesmo tipo de dados. A sintaxe na seguinte:

SELECT
   alias1.coluna, alias2.coluna, ...
FROM
   tabla1 as alias1, tabela2 as alias2
WHERE
   alias1.coluna = alias2.coluna
AND
   outras condicoes

Por exemplo, para visualizar o número, nome e posto de cada empregado, junto com o número, nome e posto do supervisor de cada um deles se utilizaria a seguinte sentença:

SELECT
   t.num_emp, t.nome, t.posto, t.num_sup,s.nome, s.posto
FROM
    empregados AS t, empregados AS s
WHERE
   t.num_sup = s.num_emp


Consultas de Combinações não Comuns

A maioria das combinações está baseada na igualdade de valores das colunas que são o critério da combinação. As não comuns se baseiam em outros operadores de combinação, tais como NOT, BETWEEN, <>, etc.

Por exemplo, para listar o grau salarial, nome, salário e posto de cada empregado ordenando o resultado por grau e salário haveria que executar a seguinte sentença:

SELECT
   graus.grau,empregados.nome, empregados.salario, empregados.posto
FROM
    empregados, graus
WHERE
   empregados.salario BETWEEN grados.salarioinferior And grados.salariosuperior
ORDER BY
   grados.grado, empregados.salario


Para listar o salário médio dentro de cada grau salarial haveria que lançar esta outra sentença:

SELECT
   graus.grau, AVG(empregados.salario)
FROM
   empregados, graus
WHERE
   empregados.salario BETWEEN graus.salarioinferior And graus.salariosuperior
GROUP BY
   graus.grau


CROSS JOIN (SQL-SERVER)

Utiliza-se em SQL-SERVER para realizar consultas de união. Suponhamos que temos uma tabela com todos os autores e outra com todos os livros. Se desejássemos obter uma listagem combinando ambas tabelas de tal forma que cada autor aparecesse junto a cada título, utilizaríamos a seguinte sintaxe:

SELECT
    Autores.Nome, Livros.Titulo
FROM
    Autores CROSS JOIN Livros


SELF JOIN

SELF JOIN é uma técnica empregada para conseguir o produto cartesiano de uma tabela consigo mesma. Sua utilização não é muito freqüente, mas colocaremos algum exemplo de sua utilização.
Suponhamos a seguinte tabela (O campo autor é numérico, embora para ilustrar o exemplo utilize o nome):

Autores
Código (Código do livro)Autor (Nome do Autor)
B00121. Francisco López
B00122. Javier Alonso
B00123. Marta Rebolledo
C00141. Francisco López
C00142. Javier Alonso
D01202. Javier Alonso
D01203. Marta Rebolledo

Queremos obter, para cada livro, pares de autores:

SELECT
    A.Codigo, A.Autor, B.Autor
FROM
   Autores A, Autores B
WHERE
   A.Codigo = B.Codigo


O resultado é o seguinte:

CódigoAutorAutor
B00121. Francisco López1. Francisco López
B00121. Francisco López2. Javier Alonso
B00121. Francisco López3. Marta Rebolledo
B00122. Javier Alonso 2. Javier Alonso
B00122. Javier Alonso 1. Francisco López
B00122. Javier Alonso 3. Marta Rebolledo
B0012 3. Marta Rebolledo 3. Marta Rebolledo
B00123. Marta Rebolledo 2. Javier Alonso
B00123. Marta Rebolledo 1. Francisco López
C0014 1. Francisco López1. Francisco López
C00141. Francisco López 2. Javier Alonso
C0014 2. Javier Alonso2. Javier Alonso
C0014 2. Javier Alonso1. Francisco López
D01202. Javier Alonso 2. Javier Alonso
D01202. Javier Alonso 3. Marta Rebolledo
D01203. Marta Rebolledo 3. Marta Rebolledo
D01203. Marta Rebolledo 2. Javier Alonso

Como podemos observar, os pares de autores se repetem em cada um dos livros, podemos omitir estas repetições da seguinte forma:

SELECT
   A.Codigo, A.Autor, B.Autor
FROM
   Autores A, Autores B
WHERE
   A.Codigo = B.Codigo AND A.Autor < B.Autor

O resultado agora é o seguinte:

CódigoAutorAutor
B00121. Francisco López 2. Javier Alonso
B00121. Francisco López 3. Marta Rebolledo
C0014 1. Francisco López2. Javier Alonso
D01202. Javier Alonso 3. Marta Rebolledo

Agora temos um conjunto de resultados em formato Autor - CoAutor.

Se na tabela de empregados quiséssemos extrair todos os possíveis pares que podemos realizar, utilizaríamos a seguinte sentença:

SELECT
    Homens.Nome, Mulheres.Nome
FROM
   Empregados Homem, Empregados Mulheres
WHERE
   Homem.Sexo = 'Homem' AND
   Mulheres.Sexo = 'Mulher' AND
    Homens.Id <>Mulheres.Id


Para concluir suponhamos a seguinte tabela:

Empregados
IdNome SeuChefe
1Marcos 6
2Lucas1
3Ana 2
4Eva 1
5Juan 6
6Antonio

Queremos obter um conjunto de resultados com o nome do empregado e o nome de seu chefe:

SELECT
    Empre.Nome, Chefes.Nome
FROM
   Empregados Empre, Empregados Chefe
WHERE
   Empre.SeuChefe = Chefes.Id

Autoria e outras referências sobre este artigo

Manuais relacionados com este artigo
Dentro de Tutorial de SQL

Categorias relacionadas
Através das categorias do nosso diretório podem ser encontrados outros tipos de recursos relacionados com este artigo:
+ Entrar em Linguagem SQL


Comentários dos visitantes
Os comentários dos visitantes são para ampliar a informação do artigo. Todos podem participar.
Acrescentar um comentário do artigo Acrescentar um comentário do artigo



Sobre nós | Copyright | Anuncie | Entrar em contato <criarweb>

Hospedado por Hostnet Hospedagem de Sites