quinta-feira, 6 de dezembro de 2012

Sql Server JOINs - SELF JOIN- Parte final

Olá pessoal, para finalizar a nossa série de artigos sobre os tipos de junções disponíveis no sql server 2008, vamos abordar agora a junção SELF JOIN. Está junção nada mais é do que uma junção entre a mesma tabela, para isso utilizamos um alias para diferenciar as tabelas. Para exemplificar a utilização desse operador vamos utilizar uma tabela temporária como mostro abaixo:


CREATE TABLE #EMPREGADO
(
ID INT ,
IDSUPERIOR INT NULL,
NOME VARCHAR(50)
)

INSERT INTO #EMPREGADO VALUES (1,NULL,'BILL')
INSERT INTO #EMPREGADO VALUES (2,1,'MARIA')
INSERT INTO #EMPREGADO VALUES (3,1,'JOSE')
INSERT INTO #EMPREGADO VALUES (4,2,'CARLOS')
INSERT INTO #EMPREGADO VALUES (5,3,'ANA')

SELECT E.ID, ISNULL(S.NOME,'PRESIDENTE') AS SUPERIOR, E.NOME 
FROM #EMPREGADO E LEFT JOIN #EMPREGADO S ON S.ID = E.IDSUPERIOR;

O resultado mostra a lista de empregados e seus superiores:


Veja que no SELF JOIN o operador utilizado é o LEFT JOIN para que o empregado sem superior (presidente) pudesse ser visualizado no resultset. Caso fosse utilizado o INNER JOIN o resultset teria apenas os empregados com chefes. Bom era isso até a próxima!

Sql Server JOINs - CROSS JOIN- Parte 5

Pessoal, neste artigo vamos falar sobre o operador CROSS JOIN. Sua função é criar um produto cartesiano entre 2 ou mais tabelas. Devemos tomar cuidado com esse operador, a depender da quantidade de tabelas e registros envolvidos a consulta poderá ser extremamente custosa. Por exemplo um cross join entre duas tabelas cada uma com 5 registros retornará um resultset com 25 registros, isso porque cada registro da primeira tabela terá uma relação com cada registro da segunda tabela! Vamos ao exemplo:

-- Tabelas temporárias

create table #FUNCIONARIO
(
 IDFUNC INT,
 NOME VARCHAR(40),
 IDDEPAR INT NULL
)
CREATE TABLE #DEPARTAMENTO
(
IDDEPAR INT,
DESCRI VARCHAR(40)
)

--Dados para teste

INSERT INTO #FUNCIONARIO VALUES(1,'MARIA',NULL)
INSERT INTO #FUNCIONARIO VALUES(2,'JOSE',NULL)
INSERT INTO #FUNCIONARIO VALUES(3,'JOAO',1)
INSERT INTO #FUNCIONARIO VALUES(4,'ANA',2)
INSERT INTO #FUNCIONARIO VALUES(5,'SILVA',3)

INSERT INTO #DEPARTAMENTO VALUES (1, 'RH')
INSERT INTO #DEPARTAMENTO VALUES (2, 'ADM')
INSERT INTO #DEPARTAMENTO VALUES (3, 'FIN')
INSERT INTO #DEPARTAMENTO VALUES (4, 'PATR')
INSERT INTO #DEPARTAMENTO VALUES (5, 'SEG')

--Select com CROSS JOIN
SELECT F.IDFUNC, F.NOME, F.IDDEPAR, D.IDDEPAR, D.DESCRI FROM #DEPARTAMENTO D CROSS JOIN #FUNCIONARIO F; 

--Resultado!

Como podem ver, cada funcionário é relacionado com um departamento independente de existir o relacionamento entre chave primária e estrangeira. Até o próximo artigo.


Sql Server JOINs - FULL OUTER JOIN- Parte 4

Olá, continuando a falar sobre os tipos de junções hoje iremos abordar a junção FULL OUTER JOIN.

O operador FULL OUTER JOIN (ou FULL JOIN) tem como função unir e retornar os dados de 2 ou mais tabelas utilizando algum dado que seja comum entre elas. De um modo geral esse dado compreende suas chaves primárias e extrangeiras. Para facilitar a compreensão, nesse artigo não vou utilizar o banco AdventureWorks. Vejamos no script abaixo os resultados que serão retornados.

-- Criar tabelas temporárias

create table #FUNCIONARIO
(
 IDFUNC INT,
 NOME VARCHAR(40),
 IDDEPAR INT NULL
)
CREATE TABLE #DEPARTAMENTO
(
IDDEPAR INT,
DESCRI VARCHAR(40)
)

-- Inserir dados para teste

INSERT INTO #FUNCIONARIO VALUES(1,'MARIA',NULL)
INSERT INTO #FUNCIONARIO VALUES(2,'JOSE',NULL)
INSERT INTO #FUNCIONARIO VALUES(3,'JOAO',1)
INSERT INTO #FUNCIONARIO VALUES(4,'ANA',2)
INSERT INTO #FUNCIONARIO VALUES(5,'SILVA',3)

INSERT INTO #DEPARTAMENTO VALUES (1, 'RH')
INSERT INTO #DEPARTAMENTO VALUES (2, 'ADM')
INSERT INTO #DEPARTAMENTO VALUES (3, 'FIN')
INSERT INTO #DEPARTAMENTO VALUES (4, 'PATR')
INSERT INTO #DEPARTAMENTO VALUES (5, 'SEG')

-- Executar select
SELECT F.IDFUNC, F.NOME, F.IDDEPAR, D.IDDEPAR, D.DESCRI FROM #DEPARTAMENTO D FULL OUTER JOIN #FUNCIONARIO F ON F.IDDEPAR = D.IDDEPAR;
-- Resultado do select

Analisando o resultado podemos chegar a conclusão que o operador FULL JOIN funciona como uma união dos operadores LEFT JOIN e RIGHT JOIN. Execute o select abaixo e compare os resultados.

-- select com union

SELECT F.IDFUNC, F.NOME, F.IDDEPAR, D.IDDEPAR, D.DESCRI FROM #DEPARTAMENTO D LEFT JOIN #FUNCIONARIO F ON F.IDDEPAR = D.IDDEPAR
UNION
SELECT F.IDFUNC, F.NOME, F.IDDEPAR, D.IDDEPAR, D.DESCRI FROM #DEPARTAMENTO D RIGHT JOIN #FUNCIONARIO F ON F.IDDEPAR = D.IDDEPAR

quarta-feira, 5 de dezembro de 2012

Sql Server JOINs - RIGHT JOIN- Parte 3

Olá pessoal, dando continuidade ao assunto de junções, hoje vamos abordar a junção RIGHT JOIN. A função desse operador é similar a do operador LEFT JOIN, a única mudança fica por conta da tabela que terá todos os seus dados retornados. Neste caso o RIGHT JOIN retornará todos os registros da tabela situada a direita do operador, na tabela da esquerda só serão retornados os dados que tiverem referência da tabela da direita. Vamos exemplificar este caso, utilizando o banco de dados AdventureWorks.

SELECT P.FirstName, P.LastName,  P.BusinessEntityID, E.BusinessEntityID,  E.VacationHours, E.SickLeaveHours
FROM HumanResources.Employee E
RIGHT OUTER JOIN Person.Person P
ON E.BusinessEntityID = P.BusinessEntityID;

Resultado:


Na imagem acima recortei apenas os 10 primeiros registros do resultado (no total são retornados 19972 registros), veja que em todos eles as 3 primeiras colunas, que são da tabela Person, contém algum dado. Como Person está do lado direito do operador RIGHT JOIN todos os registros serão retornados, independente de haver alguma referência na tabela Employee. Vamos ver mais um exemplo utilizando a imagem abaixo:

Se executassemos o seguinte select:

SELECT F.IDFUNC, F.NOME, F.IDDEPAR, D.IDDEPAR, D.DESCRI FROM #FUNCIONARIO F RIGHT JOIN #DEPARTAMENTO D ON F.IDDEPAR = D.IDDEPAR;

Teríamos o seguinte resultado:

Veja que como #DEPARTAMENTO é a tabela a direita do operador RIGHT ela teve todos os seus dados retornados, já os dados da tabela #FUNCIONARIO só são retornados aqueles que possuem departamento.