Ajuda com uma query sql

Bom dia,
Estou precisando de uma ajuda pra fazer uma query.

Tenho 3 tabelas

Numeros, Movimento, NumerosMovimento

Preciso fazer uma consulta com as seguintes condições:

  • Numeros pode existir ou não na tabela NumerosMovimento.
  • Se Numeros existir, um campo da tabela Movimento não pode ser nulo.

Obrigado pela atenção.

Boa tarde.

Pode simplesmente fazer um Join entre as tabelas e buscar as informações que necessita. Sobre as duas condições, eu diria para montar a Query no Java utilizando StringBuilder e usar dos famosos if´s :slight_smile:

Ou estou me precipitando e estamos falando unicamente da linguagem SQL?
Abraços.

Sim, fiz com join… mais ai tem o detalhe, o resultado mostra somente os numeros que não tem movimento, teria que mostrar os
que tambem tem movimento, mais somente os que o status esta OK.

a query ta assim

select sequencia,numero,movimento.codigo 
from numero
inner join numeromovimento
on numeromovimento.numero = numero.sequencia
inner join movimento
on movimento.codigo = numeromovimento.movimento
where numero.campo1 = 123 and numero.campo2 = 456
and movimento.codigo is null or movimento.status is not null
and numero.numero in

Vê se lhe dá uma luz:

select * from numeros n, movimentos m, numerosmovimentos nm where nm.numerosuid = n.numeros and nm.movimentosuid = m.movimentosuid and movimentos.status is not null

Algo assim? Só exatamente qual campo de Movimentos não pode ser Nulo?
Abraços.

[quote=Hebertbc]Sim, fiz com join… mais ai tem o detalhe, o resultado mostra somente os numeros que não tem movimento, teria que mostrar os
que tambem tem movimento, mais somente os que o status esta OK.

a query ta assim

select sequencia,numero,movimento.codigo from numero inner join numeromovimento on numeromovimento.numero = numero.sequencia inner join movimento on movimento.codigo = numeromovimento.movimento where numero.campo1 = 123 and numero.campo2 = 456 and movimento.codigo is null or movimento.status is not null and numero.numero in [/quote]

Somente uma coisa, se seu where tem “or” e “and” e não tem parênteses, alguma coisa provavelmente vai dar errado, verifique exatamente onde o “or” deve funcionar e isole essa expressão com parênteses.

select sequencia,numero,movimento.codigo from numero inner join numeromovimento on numeromovimento.numero = numero.sequencia inner join movimento on movimento.codigo = numeromovimento.movimento where (numero.campo1 = 123 and numero.campo2 = 456 and movimento.codigo is null) or (movimento.status is not null and numero.numero in ?)

Acredito que a tabela NumeroMovimento seja a tabela de ligação, certo?

não sabemos os campos das tabelas, mas digamos que sejam:

Numero
-----------------
idnumero
numero
...


Movimento
-----------------
idmovimento
movimento
...


NumeroMovimento
-----------------
idnumero
idmovimento
...

sql: não sei qual o banco de dados, mas tentei fazr usando técnica de outer join

select 
       n.numero, 
       m.movimento
from  
       numero n left join 
       numeromovimento nm on (n.numero = nm.numero)  join 
       movimento m on (nm.movimento = m.movimento) 

[quote=g4j]Acredito que a tabela NumeroMovimento seja a tabela de ligação, certo?

não sabemos os campos das tabelas, mas digamos que sejam:

Numero
-----------------
idnumero
numero
...


Movimento
-----------------
idmovimento
movimento
...


NumeroMovimento
-----------------
idnumero
idmovimento
...

sql: não sei qual o banco de dados, mas tentei fazr usando técnica de outer join

select n.numero, m.movimento from numero n left join numeromovimento nm on (n.numero = nm.numero) join movimento m on (nm.movimento = m.movimento) [/quote]

Isso mesmo, minhas tabelas tem esse formato, o detalhe que ta acontecendo é que quando numero possui um movimento em aberto ainda ele não pode sair no resultado, resolvendo com isso (movimento.status is not null) mais ae aparece o resultado dos numeros que possuem outros movimentos efetivados anteriormente.

O que eu quero é uma relação de numero que não possuem movimento + os numeros que possuem movimento efetivado.

Ex.

o numero 123 tem 5 movimentos mais somente 4 estão efetivados. (Esse resultado não deve aparecer)
o numero 456 tem 3 movimentos e os 3 estão efetivados. (Esse numero aparece no resultado)
o numero 789 num tem nenhum movimento. (Esse numero aparece no resultado)

Entendi. Mas como você sabe que o número possui movimento efetivado? Precisa testar isso no sql tambem!

[quote=g4j][quote=Hebertbc]

Isso mesmo, minhas tabelas tem esse formato, o detalhe que ta acontecendo é que quando numero possui um movimento em aberto ainda ele não pode sair no resultado, resolvendo com isso (movimento.status is not null) mais ae aparece o resultado dos numeros que possuem movimento efetivado do mesmo jeito.

O que eu quero é uma relação de numero que não possuem movimento + os numeros que possuem movimento efetivado.
[/quote]

Entendi. Mas como você sabe que o número possui movimento efetivado? Precisa testar isso no sql tambem![/quote]

na tabela movimento tem o campo status, ele não pode ser nulo

Eu sei que você postou um pouco da regra de negocio ali em cima mas, tem como detalhar melhor ? tipo postando o nome e os campos das tabelas reais ?

edit: acho que entendi, a regra seria mais ou menos assim:

vc tem por exemplo uma tabela de pessoa, e uma tabela de tipos de consulta, e numa terceira tabela voce guardaria uma consulta marcada por uma pessoa, e o status daquela consulta ?

[]'s

edit2: se for a regra acima, você com duas tabelas já da pra fazer, segue dump do mysql:

--
-- Estrutura da tabela `consultas`
--

CREATE TABLE IF NOT EXISTS `consultas` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

--
-- Extraindo dados da tabela `consultas` <----- ESSA TABELA AQUI NÃO PRECISA.
--

INSERT INTO `consultas` (`id`, `nome`) VALUES
(1, 'Pronto Socorro'),
(2, 'Enferemaria');

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

--
-- Estrutura da tabela `consultas_marcadas`
--

CREATE TABLE IF NOT EXISTS `consultas_marcadas` (
  `id_pessoa` int(11) NOT NULL,
  `id_consulta` int(11) NOT NULL,
  `status` tinyint(1) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Extraindo dados da tabela `consultas_marcadas`
--

INSERT INTO `consultas_marcadas` (`id_pessoa`, `id_consulta`, `status`) VALUES
(1, 2, NULL),
(2, 2, 1),
(3, 2, NULL),
(2, 2, NULL),
(4, 1, 1),
(2, 1, NULL);

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

--
-- Estrutura da tabela `pessoas`
--

CREATE TABLE IF NOT EXISTS `pessoas` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(255) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

--
-- Extraindo dados da tabela `pessoas`
--

INSERT INTO `pessoas` (`id`, `nome`) VALUES
(1, 'João'),
(2, 'Maria'),
(3, 'Juckinha'),
(4, 'Zezé'),
(5, 'Wryel');

SELECT que mostra a quantidade de consultas das pessoas:

SELECT pessoas.id, pessoas.nome, COUNT(consultas_marcadas.status) AS ConsultasAtivas, COUNT(consultas_marcadas.id_pessoa) TotalConsultas FROM pessoas 
LEFT JOIN consultas_marcadas ON pessoas.id = consultas_marcadas.id_pessoa 
GROUP BY pessoas.id

SELECT que mostra apenas pessoas com numero de quantidade de consultas iguais:

SELECT pessoas.id, pessoas.nome, COUNT(consultas_marcadas.status) AS ConsultasAtivas, COUNT(consultas_marcadas.id_pessoa) TotalConsultas FROM pessoas 
LEFT JOIN consultas_marcadas ON pessoas.id = consultas_marcadas.id_pessoa 
GROUP BY pessoas.id
HAVING ConsultasAtivas = TotalConsultas

lembrando que COUNT() quanto passa em um campo nulo, ele não conta(?) desde que não seja em um GROUP BY

só adaptar agora conforme sua regra de negócio :expressionless:

Certo, não lembro bem todos os campos das tabelas mais os principais são esses:


NumerosMovimento
{
id
numeroMovimentado
movimento
tipoMovimentoNumero
DataMovimentoNumero
}

Movimento
{
id
dataCadastro
dataEfetivacao
tipo
status
}

Numero
{
id
numero
idCliente
idPropriedade
}

DestinoFinal
{
id
numero
idCliente
idPropriedade
...
}

Obs. : Dependendo to tipo do movimento, após a efetivação do movimento os numeros são removidos da tabela Numero e vão pra tabela DestinFinal. Não tinha colocado a tabela DestinoFInal pq na query se já não encontrasse o numero na tabela Numero era pq o mesmo não existia ou ja tinha ido pro destino final.

[quote=Hebertbc]Certo, não lembro bem todos os campos das tabelas mais os principais são esses:

Obs. : Dependendo to tipo do movimento, após a efetivação do movimento os numeros são removidos da tabela Numero e vão pra tabela DestinFinal. Não tinha colocado a tabela DestinoFInal pq na query se já não encontrasse o numero na tabela Numero era pq o mesmo não existia ou ja tinha ido pro destino final.[/quote]

E que tipo de consulta eu deveria agora levar em consideração nessa tabela destino final ? :stuck_out_tongue:

toda via, vamos lá, vou mostrar o que eu entendi:

a primeira query você consultava com:

SELECT pessoas.id, pessoas.nome, COUNT(consultas_marcadas.status) AS ConsultasAtivas, COUNT(consultas_marcadas.id_pessoa) TotalConsultas FROM pessoas   
LEFT JOIN consultas_marcadas ON pessoas.id = consultas_marcadas.id_pessoa   
GROUP BY pessoas.id  

ai você me disse que queria consular uma segunda tabela, que la tb poderiamos ter consulta em aberto … então, eu dupliquei a tabela e apenas mudei de nome para diferenciar, dai montei a query para pegar consultas nas duas tabelas:

SELECT pessoas.id, pessoas.nome, COUNT(consultas_marcadas.status) AS ConsultasAtivas, COUNT(consultas_marcadas.id_pessoa) TotalConsultas FROM pessoas   
LEFT JOIN consultas_marcadas ON pessoas.id = consultas_marcadas.id_pessoa   
GROUP BY pessoas.id  
UNION ALL 
SELECT pessoas.id, pessoas.nome, COUNT(consultas_saidas.status) AS ConsultasAtivas, COUNT(consultas_saidas.id_pessoa) TotalConsultas FROM pessoas 
LEFT JOIN consultas_saidas ON pessoas.id = consultas_saidas.id_pessoa   
GROUP BY pessoas.id

Temos os nomes duplicados por se tratar de duas tabelas diferentes, então eu vou agrupalas para um resultado só:

SELECT nome, SUM(ConsultasAtivas), SUM(TotalConsultas) FROM ( SELECT pessoas.id, pessoas.nome, COUNT(consultas_marcadas.status) AS ConsultasAtivas, COUNT(consultas_marcadas.id_pessoa) TotalConsultas FROM pessoas   
LEFT JOIN consultas_marcadas ON pessoas.id = consultas_marcadas.id_pessoa   
GROUP BY pessoas.id  
UNION ALL 
SELECT pessoas.id, pessoas.nome, COUNT(consultas_saidas.status) AS ConsultasAtivas, COUNT(consultas_saidas.id_pessoa) TotalConsultas FROM pessoas 
LEFT JOIN consultas_saidas ON pessoas.id = consultas_saidas.id_pessoa   
GROUP BY pessoas.id ) AS NomeTemporarioProMysql 
GROUP BY id

Agora, sua condição para apenas os que ja tem consultas abertas e fechadas iguais :

SELECT nome, SUM(ConsultasAtivas) AS ativas, SUM(TotalConsultas) AS total FROM
(

SELECT pessoas.id, pessoas.nome, COUNT(consultas_marcadas.status) AS ConsultasAtivas, COUNT(consultas_marcadas.id_pessoa) TotalConsultas FROM pessoas   
LEFT JOIN consultas_marcadas ON pessoas.id = consultas_marcadas.id_pessoa   
GROUP BY pessoas.id  

UNION ALL 

SELECT pessoas.id, pessoas.nome, COUNT(consultas_saidas.status) AS ConsultasAtivas, COUNT(consultas_saidas.id_pessoa) TotalConsultas FROM pessoas 
LEFT JOIN consultas_saidas ON pessoas.id = consultas_saidas.id_pessoa   
GROUP BY pessoas.id 

) AS NomeTemporarioProMysql 
GROUP BY id 
HAVING ativas = total

Vou testar aqui e posto os resultados.