Usuário com melhor resposta
Problemas SELECT em 2 tabelas diferentes (repeticoes)

Pergunta
-
Olá a todos!!!
Estou com um problema ao selecionar dados de duas tabelas diferentes.
As tabelas sao:
Tabela [CONTAS].[dbo].[t1]:
[t1.valor1]_ [t1.valor2]_____ [t1.datetime]
2__________ 1__________ 2012-08-21 10:17:28.933
2__________ 2__________ 2012-08-21 10:17:36.460
2__________ 3__________ 2012-08-21 10:17:38.997
2__________ 4__________ 2012-08-21 10:17:40.917
2__________ 5__________ 2012-08-21 10:17:42.230
2__________ 6__________ 2012-08-21 10:17:43.393
2__________ 7__________ 2012-08-21 10:17:44.703
2__________ 8__________ 2012-08-21 10:17:46.210
2__________ 9__________ 2012-08-21 10:17:47.493
Tabela [CONTAS].[dbo].[t2] :
[t2.valor1]_ [t2.valor2]_____ [t2.datetime]
11__________ 10__________ 2012-08-21 10:18:43.507
22__________ 20__________ 2012-08-21 10:18:47.187
31__________ 30__________ 2012-08-21 10:18:50.493
45__________ 40__________ 2012-08-21 10:18:53.587
52__________ 50__________ 2012-08-21 10:18:58.030
64__________ 60__________ 2012-08-21 10:19:01.287
71__________ 70__________ 2012-08-21 10:19:05.297
82__________ 80__________ 2012-08-21 10:19:08.837
94__________ 90__________ 2012-08-21 10:19:13.417
Gostaria de sempre selecionar as 5 ultimas linhas das duas tabelas.
Estou utilizando a query abaixo, porem os ultimos resultados da tabelas 1 estao repetidos (2 e o 9):
QUERY:
SELECT top 5 *
FROM [CONTAS].[dbo].[t1],[CONTAS].[dbo].[t2]
order by [t1.datetime] desc,[t2.datetime] desc
GO
RESULTADO:
[t1.valor1]___[t1.valor2]___ [t1.datetime]____ [t2.valor1]_ [t2.valor2]_ [t2.datetime]
2________ 9_ 2012-08-21__ 10:17:47.493_____ 94______ 90___ 2012-08-21 10:19:13.417
2________ 9_ 2012-08-21__ 10:17:47.493_____ 82______ 80___ 2012-08-21 10:19:08.837
2________ 9_ 2012-08-21__ 10:17:47.493_____ 71______ 70___ 2012-08-21 10:19:05.297
2________ 9_ 2012-08-21__ 10:17:47.493_____ 64______ 60___ 2012-08-21 10:19:01.287
2________ 9_ 2012-08-21__ 10:17:47.493_____ 52______ 50___ 2012-08-21 10:18:58.030
Eu nao consigo tirar essas repeticoes do 2 e 9 da tabela 1...help me!!
Se alguem puder me ajudar ficarei muito grato!!
Agradeco a atencao desde já...
Obrigado a todos!
Respostas
-
Mas não tem problema o nome das tabelas e o nome das colunas serem diferentes. isso não inviabiliza a utilização do Union. Você só não poder fazer um Union com campos de tipos incompatíveis. você já tentou o Union?
Exemplo:
SELECT top 5 * From (Select CampoData_TabelaAAA FROM TabelaAAA UNION SELECT CampoData_TabelaBBB FROM TabelaBBB Order by T.SeuCampoData desc
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Marcado como Resposta HelioSabioni quarta-feira, 29 de agosto de 2012 19:08
-
Helio, conseguiu?
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Marcado como Resposta HelioSabioni quarta-feira, 29 de agosto de 2012 19:07
Todas as Respostas
-
As duas tabelas possuem algum campo de ligação?
Pelo que vejo são duas situações distintas, de forma que você vai precisar de dois Selects distintos, um para cada tabela:
SELECT top 5 * FROM [CONTAS].[dbo].[t1] order by [t1.datetime] desc SELECT top 5 * FROM [CONTAS].[dbo].[t2] order by [t2.datetime] desc
A menos que tenha um campo de ligação entre as duas tabelas.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
-
Essa opcao do Roberson exibiu os valores corretos que estou buscando porem nao consigo fazer operacoes entre eles.
O problema e que eu nao posso usar essas chaves primarias que vão incrementando, pois a query será usada em outro programa aonde ela nao podera ser alterada.
E necessito sempre buscar os ultimos valores escritos em duas tabelas, tenho a opcao da data que foi inserida.
Estou tentando resolver esse problema e nao encontro solucao.
Sempre esse SELECT faz o produto cartesiano que gera essa repeticao, nao sei como cancelar isso.
Obrigado pela atencao!!
abrs
-
Helio,
acho que entendi o que quer: você quer resgatar os 5 registros mais recentes entre as duas tabelas, independente de em qual esteja. É isso? Se for, seria algo como:
Create Table #Contas1 (Codigo int, Data DateTime) Create Table #Contas2 (Codigo int, Data DateTime) Insert Into #Contas1 Values (10, '08/21/2012 10:00'), (20, '08/21/2012 10:10'), (30, '08/21/2012 10:20'), (40, '08/21/2012 10:30'), (50, '08/21/2012 10:40') Insert Into #Contas2 Values (15, '08/21/2012 10:05'), (25, '08/21/2012 10:15'), (35, '08/21/2012 10:25'), (45, '08/21/2012 10:35'), (55, '08/21/2012 10:45') Select Top 5 * From (Select Codigo, Data From #Contas1 UNION Select Codigo, Data From #Contas2) T Order by T.Data desc
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Caro Roberson,
Sim preciso dos ultimos registros de 2 tabelas diferentes para efetuar operacoes, porem essas tabelas sao geradas por um software de automacao que informa somente o DATETIME como no meu exemplo citado.
Os nomes das tabelas, e nome das colunas gerados são distintos. Impossibilitando o comando UNION.
No meu exemplo fica claro que o SQL faz o produto cartesiano entre as tabelas. Nao sei como elimina-lo. Utilizando o SELECT.
Att,
Hélio
-
Mas não tem problema o nome das tabelas e o nome das colunas serem diferentes. isso não inviabiliza a utilização do Union. Você só não poder fazer um Union com campos de tipos incompatíveis. você já tentou o Union?
Exemplo:
SELECT top 5 * From (Select CampoData_TabelaAAA FROM TabelaAAA UNION SELECT CampoData_TabelaBBB FROM TabelaBBB Order by T.SeuCampoData desc
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Marcado como Resposta HelioSabioni quarta-feira, 29 de agosto de 2012 19:08
-
Cada tabela possui mais de 26 colunas na realidade.
Teria que estar selecionando 52 colunas no total das 2 tabelas juntas.
Não poderia usar o comando UNION pois apesar dos campos serem compatíveis, as unidades diferentes entre as tabelas, valores de pressao temperatura, vazão, tempo. Que não poderiam ser unidos em uma mesma coluna. Preciso mostra um gráfico de histórico de operações das ultimas 20 linhas incluídas nas duas tabelas.
Nesse seu comando:
SELECT top 5 * FROM [CONTAS].[dbo].[t1] order by [t1.datetime] desc SELECT top 5 * FROM [CONTAS].[dbo].[t2] order by [t2.datetime] desc
Exibe exatamente o que procuro, porem estão exibidos em tabelas diferentes impossibilitando operações.
Usando o meu exemplo eu precisaria de um resultado como esse:
RESULTADO:
[t1.valor1]___[t1.valor2]________ [t1.datetime]_______ [t2.valor1]_ [t2.valor2]____ [t2.datetime]
2____________ 9_______ 2012-08-21 10:17:47.493_____ 94______ 90___ 2012-08-21 10:19:13.417
2____________ 8_______ 2012-08-21 10:17:47.493_____ 82______ 80___ 2012-08-21 10:19:08.837
2____________ 7_______ 2012-08-21 10:17:47.493_____ 71______ 70___ 2012-08-21 10:19:05.297
2____________ 6_______ 2012-08-21 10:17:47.493_____ 64______ 60___ 2012-08-21 10:19:01.287
2____________ 5_______ 2012-08-21 10:17:47.493_____ 52______ 50___ 2012-08-21 10:18:58.030Parece uma coisa simples que parece não ter jeito.
A coisa esta preta aqui no serviço... ;(
Obrigado Campeão!!
-
Se os dois campos são do tipo DateTime (os campos das duas tabelas), você pode fazer o Union.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Create Table #Contas1 (Codigo int, Data DateTime) Create Table #Contas2 (Codigo int, Data DateTime) Insert Into #Contas1 Values (10, '08/21/2012 10:00'), (20, '08/21/2012 10:10'), (30, '08/21/2012 10:20'), (40, '08/21/2012 10:30'), (50, '08/21/2012 10:40') Insert Into #Contas2 Values (15, '08/21/2012 10:05'), (25, '08/21/2012 10:15'), (35, '08/21/2012 10:25'), (45, '08/21/2012 10:35'), (55, '08/21/2012 10:45') Select Top 5 * From (Select Codigo, Data From #Contas1 UNION Select Codigo, Data From #Contas2) T Order by T.Data desc
Neste caso estariamos unindo dados de 2 tabelas em uma mesma coluna, o que nao pode ser feito na minha aplicacao.
Sem contar que no caso da uniao precisa ser feita com o mesmo numero de colunas. No meu caso em certas queries preciso de 3 colunas de uma tabela e 2 de outras.
Exitem casos em que as colunas tambem nao seriam do compativeis.
Ex. tabela 1: possui custo de carvao, custo de agua , custo vapor que sao REAL.
tabela 2: possui numero de trabalhores para dividir pelo custo que sao INT.
Realmente com o comando UNION nao estou conseguindo executar esse comando.
Obrigado ;)
-
Mas Helio, se são duas situações tão distintas (com retornos distintos), você precisará fazer como eu disse em minha primeira postagem: fazer dois Selects. Um para cada situação.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Sim foi o que tinha feito a principio antes de abrir o post, porem daquela maneira nao consegui efetuar operacoes entra colunas pois estavam em tabelas diferentes. Seria possivel fazer essas operacoes?
Query:
SELECT top 5 [t2.valor1]
,[t2.valor2]
,[t2.datetime]
FROM [CONTAS].[dbo].[t2]
order by [t2.datetime] desc
SELECT top 5 [t1.valor1]
,[t1.valor2]
,[t1.datetime]
,([t1.valor1]*[t1.valor2]) as [CONTAS]
FROM [CONTAS].[dbo].[t1]
order by [t1.datetime] desc[t2.valor1] [t2.valor2] [t2.datetime]
94 90 2012-08-21 10:19:13.417
82 80 2012-08-21 10:19:08.837
71 70 2012-08-21 10:19:05.297
64 60 2012-08-21 10:19:01.287
52 50 2012-08-21 10:18:58.030[t1.valor1] [t1.valor2] [t1.datetime] [CONTAS]
2 9 2012-08-21 10:17:47.493 18
2 8 2012-08-21 10:17:46.210 16
2 7 2012-08-21 10:17:44.703 14
2 6 2012-08-21 10:17:43.393 12
2 5 2012-08-21 10:17:42.230 10
Eu so consegui fazer operações com colunas da mesma tabela.
Como ira fazer " [t2.valor1] *[t1.valor1] as [Resultado] ", o sql nao aceita pois as colunas estao em select diferentes.
Obrigado companheiro!
- Editado HelioSabioni terça-feira, 21 de agosto de 2012 18:15
-
Dessa forma não dá.
Vamos lá: você quer os 5 registros mais recentes de cada tabela, correto? É isso mesmo? Você quer os 5 mais recentes de cada tabela, separadamente? Ou seja, retornando 10 registros? Ou você quer os 5 mais recentes numa espécia de união entre as duas tabelas?
Existe algum campo que seja de ligação entre as duas tabelas? Ou seja, como você identifica que um registro de uma tabela tem a ver com o registro da outra tabela? Qual a ligação entre as contas das duas tabelas?
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Eu precisaria uma especie de uniao dos últimos registros das duas tabelas.
Desse jeito:
[t1.valor1]___[t1.valor2]________ [t1.datetime]_______ [t2.valor1]_ [t2.valor2]____ [t2.datetime]
2____________ 9_______ 2012-08-21 10:17:47.493_____ 94______ 90___ 2012-08-21 10:19:13.417
2____________ 8_______2012-08-21 10:17:46.210_____ 82______ 80___ 2012-08-21 10:19:08.837
2____________ 7_______ 2012-08-21 10:17:44.703_____ 71______ 70___ 2012-08-21 10:19:05.297
2____________ 6_______ 2012-08-21 10:17:43.393_____ 64______ 60___ 2012-08-21 10:19:01.287
2____________ 5_______ 2012-08-21 10:17:42.230_____ 52______ 50___ 2012-08-21 10:18:58.030Ai que esta o problema, nao existe campo de relacao entre as 2 tabelas. Os registros sao distindos. Apenas tenho a data aonde estou ordenado DESC para pegar o ultimos registros.
As vezes a tabela 1 permanece desatualizada, e a tabelas 2 são adicionados 5 novos registro em um dia.
Quem gera a tabela e um software de histórico, aonde não tenho como modificar nem inserir nada. Apenas pesquisar.
Essa query será inclusa em um outro software aonde sera exibido os KPIs em uma tela supervisoria.
No momento que o software gera novas novas linhas no sql, preciso busca-las e fazer contas para exibir na tela do operador.
Obrigado pela atencao!
- Editado HelioSabioni terça-feira, 21 de agosto de 2012 18:39
-
Mas são só estes 3 campos que você quer retornar: Valor1, Valor2 e Data?
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
O banco real possui 25 colunas em cada tabela.
Irei fazer muitas querys, algumas buscando até 10 colunas, nem sempre todas.
Eu fiz esse exemplo para postar no site e exemplificar meu problema.
O que acontece é que o select faz um produto cartesiano entre as duas tabelas gerando aqueles valores repetidos mostrado no exemplo.
-
Sim, aquele seu primeiro Select está errado mesmo. Ele fará o cartesiano.
A questão é que se não temos campo de ligação entre as duas tabelas, se não há uma lógica de ligação, não temos como "juntar" os resultados.
Precisamos encontrar uma lógica de ligação. Do contrário, só dando dois Selects mesmo, mas sem ligar um com o outro (cartesiano).
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Mesmo se tivesse o campo de ligacao eu nao poderia ficar mudando o campo da query, que já estaria inserida no programa.
Existe a possibilidade da tabela 1 sofrer atualizações enquanto a tabela 2 continuar desatualizada, tendo que buscar sempre os ultimos valores.
Obrigado pela atencao, acredito que como o senhor nao pode me ajudar, sera dificil outra pessoa conseguir.
Seu site e bem legal e o sr. tem muito conhecimento no assunto.
Obrigado!
- Editado HelioSabioni terça-feira, 21 de agosto de 2012 18:56
-
Obrigado.
Se tivéssemos um campo de ligação poderíamos fazer um Union somente com este campo e com as datas, e depois pegar o restante das informações.
Se eu ainda não tiver entendido a estrutura de suas tabelas e o retorno que pretende ter, talvez ainda tenha como fazer. Mas com o que entendi até aqui, não vejo viabilidade.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Caso eu conseguisse criar uma campo Identidade int que fosse incrementando.
Seria possivel ligar os ultimos valores adicionados? Mesmo se os id's fossem diferentes?
ex:
Tabela1:
t1.id__t1.valor
1__32
2__84
3__56
Tabela1:
t2.id__t2.valor
1__12
2__32
Teria como relacionar tipo fazer uma condicao ilustrando: Where maior.id.tabela1=maior.id.tabela2
Com o objetivo de obter:
t1.id__t1.valor__t2.id__t2.valor
3__56__2__32
2__84__1__12
Obrigado!
- Editado HelioSabioni terça-feira, 21 de agosto de 2012 19:29
-
Não, isso não adiantaria.
Pode postar a estrutura real das duas tabelas? (Refiro-me à estrutura, os "Create table" de cada uma.)
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Create Table Tabel1 (id1 int, valor1 real, valor2 real)
Create Table Tabel2 (id2 int, valor3 real, valor4 real, valor5 real)
Insert Into Tabel1 Values (1,10,11), (2,20,21), (3,30,31), (4,40,41)
Insert Into Tabel2 Values (1,2,22,33), (2,4,44,55), (3,8,88,99)Com essa coluna Id1 e Id2 teria como selecionar as ultimas 2 linhas adicionadas que seriam:
Tabel1 as linhas (3,30,31), (4,40,41)
Tabel2 as linhas (2,4,44,55), (3,8,88,99)
Att,
Helio
-
Mas Helio, essa é sua estrutura real? É um exemplo real? Cadê a coluna de data??
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Olha desculpe-me porem agora tenho que ir embora, pois tenho que pegar minha carona aqui em sp.
Amanha posso te enviar o backup do DataBase Original do Software, para ver existe uma solucao.
Se puder me ajudar ficarei grato companheiro.
Abrs!!
-
Tá ok. Não te prometo, mas a gente tenta manhã.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Helio Sabione,
estou sem o SQL Server instalado aqui, não consigo fazer testes, porém na minha opinião as repetições estão ocorrendo porque você está utilizando um ORDER BY COMPOSTO entre duas tabelas SEM RELACIONAMENTO ... tente utilizar a cláusula DISTINCT.
Segue sua primeira consulta com distinct:
SELECT DISTINCT TOP 5 *
FROM
[CONTAS].[dbo].[t1]
,[CONTAS].[dbo].[t2]
ORDER BY
[t1.datetime] desc ,[t2.datetime] desc
Caso tenha sido útil peço que classifique .
Abç.
-
Helio, conseguiu?
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Marcado como Resposta HelioSabioni quarta-feira, 29 de agosto de 2012 19:07
-
-
Olá.
Dependendo do que precisar, pode ser usada a função Row_Number. Mas é bom você abrir uma nova Thread caso precise, explicando e exemplificando detalhadamente a situação, como fez nesta Thread.
Abs.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.