29.01.2018, 00:20
(
Последний раз редактировалось MBJ; 27.05.2018 в 16:51.
)
Introduзгo
- O que й uma Junзгo?
Quando criamos um servidor utilizando o plugin MySQL, temos vбrias tabelas, e muitas delas sгo relacionadas, como por exemplo:
PHP код:CREATE TABLE player(
id INT(4) AUTO_INCREMENT PRIMARY KEY,
nick VARCHAR(24));
CREATE TABLE house (
id INT(4) AUTO_INCREMENT PRIMARY KEY,
player_id INT(4),
FOREIGN KEY (player_id) REFERENCES player(id) ON DELETE CASCADE);
No decorrer do desenvolvimento pode surgir o seguinte problema:
Selecionar o nome do dono da casa X(id da casa).
Como fazer isso se sу tenho o id do player na tabela house?
Tipos de JOIN - INNER JOIN
Soluзгo para questгo acima: Usar um INNER JOIN(ou somente JOIN), uma junзгo interna, este tipo de junзгo nos retorna as linhas que possuem relaзгo, como por exemplo, uma casa que possua uma dono(player), veja um exemplo:
PHP код:SELECT nick FROM player JOIN house ON house.player_id = player.id WHERE house.id = 10
- SELECT nick FROM player - selecione a coluna 'nick' da tabela 'player'
- JOIN house - junte con a tabela 'house'
- ON house.player_id = player.id - Onde a coluna 'player_id' na tabela 'house' seja igual a coluna 'id' na tabela 'player'
- WHERE house.id = 10 - E onde a coluna 'id' na tabela 'house' seja igual a 10
Mas se minha questгo for:
Mostrar o nick dos players que nгo possuem casa?
- OUTER JOIN
Soluзгo para questгo acima: Para isso utilizamos um OUTER JOIN, uma junзгo externa, que nos retorna tanto os resultados que possuem uma relaзгo, quantos os que nгo possuem, veja um exemplo:
PHP код:SELECT nick FROM player OUTER JOIN house ON house.player_id = player.id where house.player_id is null
- SELECT nick FROM player - selecione a coluna 'nick' da tabela 'player'
- OUTER JOIN house - junte con a tabela 'house' mostrando todos os resultados das duas tabelas
- ON house.player_id = player.id - Onde a coluna 'player_id' na tabela 'house' seja igual a coluna 'id' na tabela 'player'
- WHERE house.player_id is null - E onde a coluna 'player_id' na tabela 'house' seja nula, ou seja, nгo exista relacionamento entre as duas tabelas
Entгo o cуdigo correto seria este:
PHP код:SELECT nick FROM player LEFT OUTER JOIN house ON house.player_id = player.id where house.player_id is null
Lembrando que quando usamos uma junзгo precisamos comparar sempre a chave primбria de uma tabela com a chave estrangeira de outra tabela.
- AUTO RELACIONAMENTO
Outro tipo de relacionamento que possuнmos em SQL й o Auto Relacionamento, onde precisamos fazer uma consulta na mesma tabela mais de uma vez, para isso utilizamos Aliases(Apelidos) na tabela que queremos fazer a consulta, veja um exemplo:
Supondo que temos as seguintes tabelas:
PHP код:create table player(
id int(4) auto_increment primary key,
nick varchar(24));
create table friends (
player_id1 int(4),
player_id2 int(4),
// nesse caso devemos utilizar Chave Primaria Composta, onde temos mais de um campo como chave primaria
PRIMARY KEY(player_id1, player_id2),
//e faremos os relacionamentos normais para cada chave
FOREIGN KEY(player_id1) REFERENCES player(id),
FOREIGN KEY(player_id2) REFERENCES player(id)
//eu sei que existe maneira melhor para fazer o relacionamento, mas assim acho que fica mais claro para entender
);
Entгo faria o seguinte:
PHP код:SELECT p1.nick, p2.nick
FROM friends JOIN player p1 ON p1.id = friends.player_id1
JOIN player p2 ON p2.id = friends.player_id2
WHERE friends.player_id1 = 1 OR friends.player_id2 = 1
SELECT p1.nick, p2.nick FROM friends - Selecione a coluna nick das tabelas p1 e p2
FROM friends JOIN player p1 ON p1.id = friends.player_id1 - Selecione da tabela friends e junte com a tabela player. Repare que ao lado do nome da tabela colocamos seu apelido, no caso p1, a partir daqui sempre que formos nos referencias a esta tabela utilizamos o apelido dado a ela e nгo seu nome
JOIN player p2 ON p2.id = friends.player_id2 - faзo outro join na tabela player porйm alterando seu apelido, isso faz com que o SGBD trate a tabela p1 e p2 como duas tabelas diferentes
WHERE friends.player_id1 = 1 OR friends.player_id2 = 1 - Comparamos as chaves primarias da tabela friends para termos apenas os resultados em que meu ID esta cadastrado
O resultado no final й esse:
@ATUALIZAЗГO - INNER JOIN junto com UPDATE
Quando possuimos tabelas relacionadas, as vezes precisamos atualizar os dados em mais de uma tabela, o mйtodo mais comum й usar dois UPDATE's, um para cada tabela alterada, porйm isto pode ser simplificado em apenas uma consulta, como no exemplo:
Temos as seguintes tabelas:
PHP код:CREATE TABLE player(
id INT(4) AUTO_INCREMENT PRIMARY KEY,
nick VARCHAR(24),
money INT(9));
CREATE TABLE house (
id INT(4) AUTO_INCREMENT PRIMARY KEY,
player_id INT(4),
safe int(9), //dinheiro no cofre da casa
rent int(5), //valor do aluguel da casaa
FOREIGN KEY (player_id) REFERENCES player(id) ON DELETE CASCADE);
PHP код:UPDATE player JOIN house //junto a tabea player e a tabela house
SET player.money = player.money - house.rent, house.safe = hosue.safe + house.rent //atualizo os valores nas duas tabelas
WHERE house.player = player.id //comparo chave primaria com chave estrangeira