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

Instrução SQL

Discussão em 'Programação' iniciada por pfcs, 9 de Janeiro de 2007. (Respostas: 12; Visualizações: 1072)

  1. Boas pessoal,

    Tenho numa BD de horarios de autocarros esta tabela..


    id_viagem id_localidade

    1 1
    1 2
    1 3
    1 4
    1 5
    1 6
    1 7
    1 8
    1 9
    2 1
    2 2
    2 3
    2 4

    Agora gostava de saber se é possivel fazer uma instrução de SQL que me devolva o id da viagem que passa em duas certas localidades..

    Exemplo:
    devolver a viagem que passa nas localidades com id 2 e 7
    devolveria apenas a viagem com o id 1, já que a 2 apenas passa na localidade 2 mas não na 7..


    Alguém me pode dar uma ajudinha? É que me parecia ser fácil fazer este sql mas afinal não estou a conseguir..
    [​IMG]
     
  2. HecKel

    HecKel The WORM

    Não me parece assim tão trivial quanto isso...

    Tenta isto:

    Código:
     Select id_viagem 
    from (
       select id_viagem 
       from TABELA_DAS_VIAGENS 
       where id_localidade=2) 
    inner join (
       select id_viagem 
       from TABELA_DAS_VIAGENS 
       where id_localidade=7) using (id_viagem)
    Tentando traduzir...

    Se criares uma tabela com as viagens que passam na localidade 2 e outra tabela com as viagens que passam na localidade 7 e fizeres a intercepção de ambas obtens a lista de viagens que passam em ambas as localidades.

    Isto teoricamente, não testei absolutamente nada disso e não garanto a fiabilidade do código.

    De notar que o código que te dei não é propriamente o mais optimizado também...

    abraços, HecKel
     
  3. Ragnarok

    Ragnarok Folding Member

    Código:
    SELECT id_viagem
    FROM Viagem
    WHERE id_location = [I]localidade1[/I] AND id_viagem in 
    (SELECT id_viagem 
    FROM Viagem 
    WHERE id_location = [I]localidade2[/I])
    
    Não testei por isso não sei se está bom mas a olho nu parece-me que sim.

    EDIT: Desculpa a má identação mas este editor de posts não dá para mais.
     
    Última edição: 9 de Janeiro de 2007
  4. Obrigado aos dois..

    A solução do HecKel não me deu porque deu um erro no inner join.
    Tentei a do Ragnarok e deu-me logo..

    Abraços e obrigado
     
  5. KiKas

    KiKas Power Member

    Usa a teoria dos conjuntos. Intersect neste caso:

    caso estejas a usar oracle:

    select id_viagem from viagem where id_location = localidade1
    INTERSECT
    select id_viagem from viagem where id_location = localidade2
     
  6. HecKel

    HecKel The WORM

    já agora, que erro deu? :P

    Naquele caso julgo que bastava um natural inner join omitindo o using, mas tal como te disse..., não garantia a fiabilidade do código.

    A solução da KiKas é bastante similar à minha, no entanto mais perceptível. Apesar de estar mais restricta ao oracle.

    abraços, HecKel
     
  7. HecKel, deu-me este erro...

    Server: Msg 156, Level 15, State 1, Line 6
    Incorrect syntax near the keyword 'inner'.
    Server: Msg 170, Level 15, State 1, Line 9
    Line 9: Incorrect syntax near 'using'.


    Realmente com a outra solução consegui retornar apenas as viagens que passavam nas duas localidades..


    Mas agora tenho outro problema porque a minha ideia era retornar não só o id da viagem, mas o id da viagem, o id da localidade e a hora para todas as viagens que passasem nos 2 locais..

    Tipo, para as localidades 2 e 7, como ia devolver apenas a viagem 1 ia-me mostrar o seguinte

    1 1 7:00
    1 2 8:00
    1 3 9:00
    1 4 10:00
    1 5 11:00
    1 6 12:00
    1 7 13:00
    1 8 14:00

    Mas neste momento está apenas a devolver a seguinte linha
    1 2 8:00


    Há forma de devolver as outras linhas também??
     
  8. HecKel

    HecKel The WORM

    Que SGBD usas? Para isso nem reconhecer o inner..., é mesmo muito estranho :X

    Da forma como te indiquei deveria aparecer ambas as linhas, da forma como o Ragnarok indicou, ele dá prioridade à localidade1 (julgo eu de que), daí obteres apenas uma linha.

    Agora se o inner não é identificado pelo SGBD sugiro-te o seguinte:
    Código:
     Select A.id_viagem 
    from (
       select id_viagem 
       from TABELA_DAS_VIAGENS 
       where id_localidade=2) A, (
       select id_viagem 
       from TABELA_DAS_VIAGENS where id_localidade=7) B
    where A.id_viagem = B.id_viagem
    (outro que não garanto que funcione :X)

    abraços, HecKel
     
  9. Ragnarok

    Ragnarok Folding Member

    Com o Intersect (que, na minha opinião, é a melhor solução apresentada e, já agora, está no standard do SQL) penso que basta usares INTERSECT ALL em vez de INTERSECT.

    Essa solução também deve funcionar, mas é melhor colocar AS depois da definição de cada uma das tabelas, ou seja:

    Código:
     Select A.id_viagem 
    from (
       select id_viagem 
       from TABELA_DAS_VIAGENS 
       where id_localidade=2) AS A, (
       select id_viagem 
       from TABELA_DAS_VIAGENS where id_localidade=7) AS B
    where A.id_viagem = B.id_viagem
    De qualquer maneira, o INTERSECT é bem mais elegante. ;)
    Quanto à minha solução, tens razão, a minha não permite apresentar o que ele quer.
     
    Última edição: 9 de Janeiro de 2007
  10. HecKel

    HecKel The WORM

  11. Ragnarok

    Ragnarok Folding Member

    Pois, eu seu que é. É pena é que os SBGD's nem sempre implementam o standard. O MySQL então é uma alegria...
     
  12. HecKel

    HecKel The WORM

    Sobre o teu edit :P no outro post...

    Agora deixaste-me na dúvida..., no SQL do Oracle não é admitido o AS nas declarações de tabelas, é apenas colocado um espaço. O AS é na redefinição do nome dos campos (na parte do Select).

    Mas ya, tens razão :P Acabei de confimar que não é standard..., http://www.w3schools.com/sql/sql_alias.asp

    E em oracle: http://www.ss64.com/ora/select.html (daí o meu erro :()

    abraços, HecKel
     
  13. Obrigadão...

    É isso mesmo, assim o meu problema já está resolvido.

    Abraços
     

Partilhar esta Página