Jump to content
Sir Pereira

Join com AND e OR

Recommended Posts

Sir Pereira

SELECT scie_users.nome AS cat_nome,scie_users_cats.id AS cat_id,scie_users.id AS user_id,scie_users.nome AS user_nome,scie_msgs.de_tipo AS msg_detipo,scie_msgs.hora AS msg_hora,scie_msgs.assunto AS msg_assunto,scie_msgs.de,scie_msgs.id AS msg_id,scie_msgs.para
FROM scie_msgs,scie_users,scie_users_cats
WHERE scie_msgs.para = '6666666' AND scie_msgs.de = scie_users.id OR scie_msgs.de = scie_users_cats.id
ORDER BY scie_msgs.hora DESC

Boas pessoal, estou a tentar listar as mensagens recebidas para um utilizador, as mensagens tanto podem ser de um individual ou de uma categoria, como tal queria retornar logo no JOIN os valores dos nomes das categorias e/ou dos nomes das pessoas.

No entanto, com esta query, está-me a juntar pessoas que nunca me enviaram "mensagens". Já estou baralhado com o meu próprio código.

Alguém que perceba o que eu quero que me consiga dar uma mãozinha?  😳

Abraço e obrigado.

Share this post


Link to post
Share on other sites
brunoais

Não está especificado qual é a ordem pela qual o AND e o OR são executados. Usa parêntesis para garantir que é executado na ordem que queres.

Por exemplo:

SELECT scie_users.nome AS cat_nome,scie_users_cats.id AS cat_id,scie_users.id AS user_id,scie_users.nome AS user_nome,scie_msgs.de_tipo AS msg_detipo,scie_msgs.hora AS msg_hora,scie_msgs.assunto AS msg_assunto,scie_msgs.de,scie_msgs.id AS msg_id,scie_msgs.para
FROM scie_msgs,scie_users,scie_users_cats
WHERE scie_msgs.para = '6666666' AND (scie_msgs.de = scie_users.id OR scie_msgs.de = scie_users_cats.id)
ORDER BY scie_msgs.hora DESC


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
brunoais

Experimenta por só uma tabela no FROM. E junta o resto usando o JOIN (INNER JOIN).


"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Share this post


Link to post
Share on other sites
Sir Pereira

Nunca trabalhei muito com INNER JOINs pelo que se fiz isto bem, saiu-me exactamente a mesma result:

SELECT scie_users.nome AS cat_nome, scie_users_cats.id AS cat_id, scie_users.id AS user_id, scie_users.nome AS user_nome, scie_msgs.de_tipo AS msg_detipo, scie_msgs.hora AS msg_hora, scie_msgs.assunto AS msg_assunto, scie_msgs.de, scie_msgs.id AS msg_id, scie_msgs.para
FROM scie_msgs
INNER JOIN scie_users, scie_users_cats
WHERE scie_msgs.para = '6666666'
AND (
scie_msgs.de = scie_users.id
OR scie_msgs.de = scie_users_cats.id
)
ORDER BY scie_msgs.hora DESC

Epa, isto tá um bocado estranho.

Share this post


Link to post
Share on other sites
Caça

A tabela "scie_msgs" nem sempre é relacionada com a "scie_user" nem com a "scie_users_cats" ao mesmo tempo, o que a leva a trazer registos que não tem nada a ver com os pretendidos.

Deverias utilizar LeftJoins ou RightJoins, dependendo da maneira que constróis a Query.


Pedro Martins

Não respondo a duvidas por PM

Share this post


Link to post
Share on other sites
Caça

Acho que não consegues evitar, tenta adaptar esta Query

SELECT scie_users.nome AS cat_nome,scie_users_cats.id AS cat_id,scie_users.id AS user_id,scie_users.nome AS user_nome,scie_msgs.de_tipo AS msg_detipo,scie_msgs.hora AS msg_hora,scie_msgs.assunto AS msg_assunto,scie_msgs.de,scie_msgs.id AS msg_id,scie_msgs.para
FROM scie_msgs 
LEFT JOIN scie_users 
ON scie_msgs.de = scie_users.id 
LEFT JOIN scie_users_cats 
ON scie_users_cats
WHERE scie_msgs.para = '6666666'
ORDER BY scie_msgs.hora DESC

Caso não exista um registo relacionado na tabela scie_users ou na tabela scie_users_cats, o registo da tabela scie_msgs continua a aparecer, mas os campos da tabela onde o registo não consta lá ficam a null


Pedro Martins

Não respondo a duvidas por PM

Share this post


Link to post
Share on other sites
Caça

Quanto menos vezes precisares de ir ao servidor, melhor :thumbsup:


Pedro Martins

Não respondo a duvidas por PM

Share this post


Link to post
Share on other sites
mjamado
Quanto menos vezes precisares de ir ao servidor, melhor :thumbsup:

Esse argumento já cansa... 👎

Se, para se poupar pedidos ao MySQL, se acabar com uma query com quatro JOINS e meia dúzia de condições, mais GROUP e ORDER, tudo o que poupaste em requests, gastaste em pancada na performance da query. Usa o EXPLAIN e verás.

Além disso, em casos normais, o MySQL está na mesma máquina do pedido ou, in extremis, na mesma subnet, o que quer dizer que os tempos dos pedidos, quando comparados com os tempos das queries, são negligenciáveis.

Queries separadas é por onde se começa (aliás, cada tabela deveria ter uma classe modelo associada, e é a essa que pedes os dados relevantes) - só muito depois, com a afluência de visitas, se identificam os reais problemas de performance.

Premature optimization is the root of all evil, Donald Knuth dixit.


"Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.