Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2001
    Messaggi
    56

    Query equivalente senza subquery

    Salve,

    ho problemi a scrivere una query che con il supporto alle subquery sarebbe sempliciotta ma che in mysql 4.0.x non e' supportata.

    Scenario: le tabelle interessate sono

    camere( camere associate ad ogni offerta - allotment )
    +----+--------+--------------+
    | id | camera | id_allotment |
    +----+--------+--------------+

    prenotazioni ( effettuate dai clienti )
    +----+-----------+-----+----+--------------+----------------+
    | id | id_camera | dal | al | id_allotment | data_emissione |
    +----+-----------+-----+----+--------------+----------------+

    A titolo informativo c'è la tabella allotment che non e' coinvolta nella query.

    Allora, la entry in camere potrebbero essere le seguenti:

    (0, 1, 1)
    (1, 2, 1)
    (2, 3, 2)

    In prenotazioni invece ci potrebbero essere la seguente entry:

    (0, 1, 10/02/2005, 14,02,2005, 1, 10/01/2005)
    (0, 1, 19/02/2005, 19,02,2005, 1, 10/01/2005)


    Adesso io ipotizzo che l'utente abbia inserito le sue informazioni
    per prenotare una camere relativa all'allotment 1, dal 15 al 17.

    Il metodo per effettuare la ricerca e' il seguente:

    1. cerco in `prenotazioni` tutte quelle per camere relative allo stesso allotment prenotate per un periodo che s'interseca con quello richiesto dall'utente: queste sono le camere che *non* posso scegliere

    2. cerco in `camere` gli allotment l'identificativo di tutte le camere che non compaiono nella query al passo 1.

    In SQL la query dovrebbe essere ( più o meno ) una cosa del genere:

    a=giorno di ingresso in camera voluto dall'utente
    b=giorno di uscita dalla camera

    select id from camere where id not in
    ( select * from prenotazioni where id_allotment=1 and
    ( ( a>dal and a<al ) or ( a>dal and a<al ) );

    Cosa dovrebbe succedere:

    la condizione della II query impone che siano scelte tutte le entry con l'intervallo temporale accavallato a quello che mi interessa; nel caso in cui non ce ne siano ottengo un insieme vuoto e quindi la query esterna mi ritornerebbe tutte le camere, potendone scegliere quindi una a piacere.

    Adesso non potendo usufruire della subqueries, non sono riuscito a creare una query equivalente con left join come suggerisce il manuale mysql; lo scenario che me la fa fallire e' quello nel quale la seconda query torna
    l'insieme vuoto, perche' essendo una join....

    Qualcuno saprebbe aiutarmi ?
    Grazie,
    j0k3r

  2. #2
    Utente di HTML.it L'avatar di chris
    Registrato dal
    Sep 1999
    Messaggi
    1,568
    codice:
    SELECT DISTINCT(c.id), p.id AS prenotata FROM camere AS c, prenotazioni AS p ON (c.id = p.id_camera) WHERE id_allotment = 1 AND ( ( a>dal and a<al ) or ( a>dal and a<al ) );
    Questa dovrebbe tirare fuori tutti i record presentando un NULL per il campo "prenotata" quando la stanza è libera.

    Le subquery dovrebbero essere supportate dalla versione 4.1 disponibile in download come versione consigliata. Potresti prendere in considerazione l'idea di comunicarlo al tuo provider.
    "Nei prossimi tre anni col mio governo vogliamo vincere anche il cancro, che colpisce ogni anno 250.000 italiani e riguarda quasi due milioni di nostri concittadini"

  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2001
    Messaggi
    56
    Ti avverto che se funziona convoliamo a nozze....

  4. #4
    Utente di HTML.it
    Registrato dal
    Aug 2001
    Messaggi
    56
    [supersaibal]Originariamente inviato da chris
    codice:
    SELECT DISTINCT(c.id), p.id AS prenotata FROM camere AS c, prenotazioni AS p ON (c.id = p.id_camera) WHERE id_allotment = 1 AND ( ( a>dal and a<al ) or ( a>dal and a<al ) );
    Questa dovrebbe tirare fuori tutti i record presentando un NULL per il campo "prenotata" quando la stanza è libera.

    Le subquery dovrebbero essere supportate dalla versione 4.1 disponibile in download come versione consigliata. Potresti prendere in considerazione l'idea di comunicarlo al tuo provider. [/supersaibal]
    SELECT DISTINCT (
    c.id
    ), p.id AS prenotata
    FROM mos_camere AS c, mos_prenotazioni AS p ON ( c.id = p.id_camera )
    WHERE mos_prenotazioni.id_allotment =1
    AND (
    (
    '2005-02-12' >= mos_prenotazioni.dal
    AND '2005-02-12' <= mos_prenotazioni.al
    )
    OR (
    '2005-02-19' >= mos_prenotazioni.dal
    AND '2005-02-19' <= mos_prenotazioni.al
    )
    )
    LIMIT 0 , 30

    Stesso errore 1064:

    #1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON (c.id = p.id_camera) WHERE mos_prenotazioni.id_allotment=1 A

    E' un errore nella query oppure NEANCHE questa sintassi e' supportata ?

    EDIT: sembra che il problema sia la clausola ON...

  5. #5
    Utente di HTML.it L'avatar di chris
    Registrato dal
    Sep 1999
    Messaggi
    1,568
    [supersaibal]Originariamente inviato da j0k3r
    E' un errore nella query oppure NEANCHE questa sintassi e' supportata ?

    EDIT: sembra che il problema sia la clausola ON... [/supersaibal]
    Mi sono accorto di aver tralasciato la left join.

    SELECT DISTINCT (
    c.id
    ), p.id AS prenotata
    FROM mos_camere AS c, mos_prenotazioni AS p ON ( c.id = p.id_camera )
    WHERE mos_prenotazioni.id_allotment =1
    AND (
    (
    '2005-02-12' >= mos_prenotazioni.dal
    AND '2005-02-12' <= mos_prenotazioni.al
    )
    OR (
    '2005-02-19' >= mos_prenotazioni.dal
    AND '2005-02-19' <= mos_prenotazioni.al
    )
    )
    LIMIT 0 , 30
    "Nei prossimi tre anni col mio governo vogliamo vincere anche il cancro, che colpisce ogni anno 250.000 italiani e riguarda quasi due milioni di nostri concittadini"

  6. #6
    Utente di HTML.it
    Registrato dal
    Aug 2001
    Messaggi
    56
    E questa era la soluzione a cui ero arrivato

    SELECT mos_camere.id, mos_camere.camera
    FROM mos_camere
    LEFT JOIN mos_prenotazioni ON ( mos_camere.id <> mos_prenotazioni.id_camera
    AND mos_prenotazioni.id_allotment =1 )
    WHERE (
    mos_prenotazioni.dal > '2005-02-12'
    OR mos_prenotazioni.al < '2005-02-14'
    )
    OR (
    (
    mos_prenotazioni.dal <= '2005-02-12'
    AND mos_prenotazioni.al >= '2005-02-12'
    )
    OR (
    mos_prenotazioni.dal <= '2005-02-14'
    AND mos_prenotazioni.al >= '2005-02-14'
    )
    )
    LIMIT 0 , 30

    Grazie, mi hai comunque messo sulla strada giusta...

  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2001
    Messaggi
    56
    [supersaibal]Originariamente inviato da chris
    Mi sono accorto di aver tralasciato la left join.

    SELECT DISTINCT (
    c.id
    ), p.id AS prenotata
    FROM mos_camere AS c, mos_prenotazioni AS p ON ( c.id = p.id_camera )
    WHERE mos_prenotazioni.id_allotment =1
    AND (
    (
    '2005-02-12' >= mos_prenotazioni.dal
    AND '2005-02-12' <= mos_prenotazioni.al
    )
    OR (
    '2005-02-19' >= mos_prenotazioni.dal
    AND '2005-02-19' <= mos_prenotazioni.al
    )
    )
    LIMIT 0 , 30 [/supersaibal]
    Beh, ancora non c'e'

    Cosi' non funge ( cioe' uo' anche non tornarmi NULLA ):

    SELECT DISTINCT (
    c.id
    ), p.id AS prenotata
    FROM mos_camere AS c, mos_prenotazioni AS p
    LEFT JOIN mos_prenotazioni ON ( c.id = p.id_camera )
    WHERE mos_prenotazioni.id_allotment =1
    AND (
    (
    '2005-02-12' >= mos_prenotazioni.dal
    AND '2005-02-12' <= mos_prenotazioni.al
    )
    OR (
    '2005-02-19' >= mos_prenotazioni.dal
    AND '2005-02-19' <= mos_prenotazioni.al
    )
    )
    LIMIT 0 , 30

  8. #8
    Utente di HTML.it L'avatar di chris
    Registrato dal
    Sep 1999
    Messaggi
    1,568
    e non puoi filtrare i dati non buoni via php?
    "Nei prossimi tre anni col mio governo vogliamo vincere anche il cancro, che colpisce ogni anno 250.000 italiani e riguarda quasi due milioni di nostri concittadini"

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.