1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Ajuda em SQL

Discussão em 'Programação' iniciada por MrOverclock, 8 de Maio de 2009. (Respostas: 30; Visualizações: 1463)

  1. MrOverclock

    MrOverclock Power Member

    Pessoal, ando aqui há 2 dias de volta de um SELECT que não sei ao certo como fazer e os conhecimentos que tenho ou são insuficientes ou estou simplesmente a pensar de maneira errada.

    Ora vamos ao que interessa, tenho uma tabela deste género:

    Treinos(treino_id, user_id, (...), distancia)

    Um utilizador depois de um treino coloca aqui a distancia que percorreu nesse treino entre outras informações que não interessam agora para o caso.


    eu queria duas coisas.

    1ª - Obter uma lista da distancia total que cada utilizador já percorreu

    2ª - (esta depois da 1ª fica fácil para mim) O utilizador que já percorreu uma distancia maior.

    Usando o PHP eu posso fazer um ciclo e safo-me. Mas não queria usar o PHP para iso, caso fosse possivel usar apenas o SQL!
     
  2. AliFromCairo

    AliFromCairo Power Member

    Boas, precisas de utilizar a cláusula GROUP BY, de modo a poderes somar as distâncias por utilizador, ou seja, algo do género:

    Código:
    SELECT user_id, SUM(distancia) AS DistanciaTotal
    FROM Treinos
    GROUP BY user_id
    
    Em relação à outra query, uma opção é alterares a query anterior, de forma a ordenares o resultado pela coluna DistanciaTotal, e limitares os resultados a um único registo (LIMIT no MySQL, TOP no SQL Server). Qualquer dúvida, coloca aqui, mas penso que era interessante tentares resolver esta.

    Espero que ajude.
     
  3. MrOverclock

    MrOverclock Power Member

    Obrigado, ajudaste e muito!

    Eu pensei que desse para usar a função MAX() mas ou estou a fazer mal ou então não é possivel... Vou tentar a tua opção com o LIMIT
     
  4. AliFromCairo

    AliFromCairo Power Member

    Repara, o que o GROUP BY faz é agrupar os registos pela(s) coluna(s) que tu colocas na cláusula; neste caso, a coluna user_id, ou seja, agrupa os registos por utilizador. Em seguida, podes calcular os valores agregados (SUM, MAX, AVG, et cetera) para um determinado atributo.

    Por exemplo, o que o SUM(distancia) faz é somar todas as distâncias para cada user_id, e devolver um registo único contendo o user_id (projectado no SELECT), e o resultado da soma. Por outro lado, o MAX(distancia) devolve a maior distância que um utilizador já fez, o que não corresponde ao que pretendes, uma vez que tu queres a maior distância total, i.e., a maior soma das distâncias.

    Sendo assim, e uma vez que na query que coloquei, tu obténs para cada utilizador a distância total que ele percorreu, precisas apenas de ordenar este resultado pela distância total, e limitares o resultado final a um único registo, que é aquele que irá conter o utilizador que percorreu a maior distância total.

    Qualquer dúvida, não hesites em colocar aqui.
     
  5. MrOverclock

    MrOverclock Power Member

    Bom post sim senhor!!

    Gostei bastante do esclarecimento! Base de dados é uma coisa que gosto muito, mas que ainda não domino... Um gajo anda a dormir nas aulas, depois quando preciso mesmo a sério tenho que vir pedir ajuda :p Eu lembro-me de ter falado disso tudo na aula... Não me lembrava era de nada!


    Agora está a acontecer-me uma coisa estranha
    (para facilitar meti outro Select)

    SELECT SUM(distancia)
    FROM treinos
    WHERE user_id = 24

    o campo distancias é SEMPRE preenchido apenas com valores até duas casas decimais, e neste caso está a dar-me este valor:

    SUM(distancia)
    1064.010002017

    Não é que faça muita diferença, mas não deixa de ser estranho... há explicação para isto? Ou já não sei nada de matemática?
     
    Última edição: 8 de Maio de 2009
  6. AliFromCairo

    AliFromCairo Power Member

    Sim, há explicação :007:. Os tipos FLOAT e DOUBLE são tipos inexactos/aproximados, e podem introduzir erros durante os cálculos. Se puderes viver com as aproximações, então podes continuar a utilizar esses tipos; caso contrário, podes utilizar o tipo DECIMAL.
     
  7. MrOverclock

    MrOverclock Power Member

    Muito obrigado mais uma vez!

    Porra... Acho que já aprendi mais hoje em duas dúzias de linhas do que numa aula inteira de SQL (2h cada) em que eu esteja com atenção! :p.
     
  8. AliFromCairo

    AliFromCairo Power Member

    Ora essa :007:. Experimenta executar a seguinte query, para teres uma noção do tal "fenómeno" de que te falava:

    Código:
    SELECT (1/200.1)*200.1
    
    Nota também que isto não é um "problema" do MySQL, mas sim da forma como os números em vírgula flutuante são representados.
     
  9. MrOverclock

    MrOverclock Power Member

    Experimentei isso e o resultado deu 1.000, adicionei dois zeros em cada um dos lados e já deu 0.99998

    Já deu para perceber bem o "problema"
     
  10. MrOverclock

    MrOverclock Power Member

    Olá novamente,

    Tenho agora, por razões que não vou estar a explicar, a mesma base de dados em dois sítios, e foi utilizada (actualizada com novos dados) em paralelo uma com a outra, agora estavam bem era se conseguisse juntar tudo numa só... Como devo proceder?


    Ou seja, tenho tabelas que têm cenas do género:

    Tabela XPT0 da BD principal
    ID dados
    (...) (...)
    321 XXX
    322 ABC
    323 DEF
    324 PQR

    e outra tipo gémea da anterior:

    Tabela XPT0 da BD secundária
    ID dados
    (...) (...)
    321 XXX
    322 GHI
    323 JKL
    324 MNO

    O que quero é colocar os dados da 2ª BD na 1ª, o ID não precisa ser o mesmo. Não há nada que mude se eles mudarem. Não precisa ficar por ordem. Por ex: o 324 da 1ª tabela, embora tenha sido posto depois do 324 da 2ª, não precisa ficar por essa ordem, é irrelevante ;)

    Tenho em toda a BD apenas uma tabela em que o ID se for mudado me pode causar problemas, mas como julgo só ter 1 linha (ou talvez nenhuma) na 2ª tabela, julgo que posso tratar disso à mão!
     
  11. Não consegui perceber o que necessitas...

    Se forem BD distintas não consegues juntar isso só com SQL... se forem tabelas ainda se consegue arranjar...

    se for para juntar os resultados de duas tabelas podes usar union....

    select id, dados from tabela1
    union all
    select id, dados from tabela2

    Com isto ficas com tudo, incluindo duplicados se tiveres a mesma entrada nas 2 tabelas.
    Se quiseres separado penso que existe o comando intersect (mas acho que depende da DB).

    Mas se conseguires explicar doutra maneira o que queres talvez eu percebe e te consiga ajudar mais.
     
  12. MrOverclock

    MrOverclock Power Member

    Tenho uma base de dados que a certo ponto foi colocada a trabalhar em paralelo com uma cópia de ela própria, de maneira que alguns utilizadores introduziram dados na "original" e outros introduziram os seus dados na "copia"

    Agora o que eu quero é pegar nos dados que estão na "cópia" e que não estão na original, adicionar à original e desaparecer com a "cópia" sem perder dados nem ficar com dados repetidos.

    Provavelmente vou fazer isto à mão, também não é nada do outro mundo.
    Faço backup em SQL da BD cópia, pego nos dados que quero e faço insert na outra.

    Eu é que pensei que pudesse haver uma maneira mais simples de fazer isto. Também já era tarde quando escrevi aquilo.
     
  13. Tomb4000

    Tomb4000 Power Member

    Oi??
    Que estas a dizer?
    Então para que serve isto:

    SELECT campo1, campo2 FROM bd1.tabela1, bd2.tabela2........

    Fazes a query normalmente mas indicas claro qual a base de dados ao qual te queres ligar.
     
  14. petersaints

    petersaints Power Member

    Penso que o que pretendes só funcionaria se fosse previamente previsto e montado algum sistema de replicação de bases de dados.
     
  15. Com bases de dados em servidores diferentes?
    É que não me faz sentido que tenhas replicação para o mesmo servidor...
     
  16. Tomb4000

    Tomb4000 Power Member

    Se for SGBD's diferentes não tenho conhecimentos que exista dblinks em mysql.

    Mas ele só mensionou que estava noutra base de dados não deixou claro que estivessem em maquinas diferentes.


    E a tua afirmação é evidente:
    " Se forem BD distintas não consegues juntar isso só com SQL... se forem tabelas ainda se consegue arranjar..."

    O que eu fiz questao de contestar porque está aí uma frase realmente enganosa.

    Quanto à replicacao, ainda ontem me aconteceu o caso que tinha uma BD de backup que tive de juntar com uma BD a correr e na mesma maquina. Não faz sentido?
     
  17. Thorak

    Thorak Power Member

    Em mysql não dá para fazer uma coisa parecida com esta ?

    SELECT aaaa,bbbb,ccccc
    INTO Persons_Backup IN 'Backup.mdb'
    FROM Persons where ......

    Em Access e SQL Server dá !
     
  18. Normalmente não associo replicação a backup... mas ok, concordo que há casos em que me faz sentido fazer backup na mesma máquina.
    Quanto a replicação de base de dados, se for para ter as 2 online não me faz muito sentido estarem na mesma máquina, ou pelo menos na mesma "instância".

    Não sei exactamente quais os termos correctos em SQLServer ou MySQL, mas em Oracle (que é o que normalmente uso) penso que não consegues correr um sql nas 2 instâncias em simultâneo.
     
  19. Penso que isso depende do "interpretador de SQL" não é SQL Standard...
     
  20. Tens razão.
     

Partilhar esta Página