Subquery

di il
11 risposte

Subquery

Salve ragazzi,

stavo facendo degli esercizi sulle subquery.

Ho 3 tabelle, fattura,cliente e dett_fattura ed ho scritto una query che mi restituisce id_cliente, la regione sociale, la partita iva, l'id della fattura, la data e il totale imponibile di tutte le fatture che erogate dal 01/01/2016 all' 11/11/2016 in cui la quantità di qualsiasi prodotto sia maggiore di 3.
SELECT 
c.ID_CLIENTE, c.RAG_SOC, c.PARTITA_IVA, f.ID_FATTURA, f.TOTALE_IMPONIBILE, f.data
FROM  dett_fattura d,fattura f, cliente c
where f.ID_FATTURA = d.ID_FATTURA AND f.ID_CLIENTE = c.ID_CLIENTE AND 
f.data BETWEEN to_date('01/01/2016', 'dd/mm/yyyy') AND to_date('11/11/2016', 'dd/mm/yyyy') and d.QUANTITA_PRODOTTO > 3 
order by c.RAG_SOC;
questa query fa quello che deve fare.

Ora vorrei avere lo stesso risultato non mettendo in join nessuna tabella ma usando delle subquery.

Si può fare?

11 Risposte

  • Re: Subquery

    Certo, ma a che pro? A mio avviso, in questo caso, nessuno.
    Ottieni solo il risultato di far lavorare molto di più il motore del database, e se per caso non vi sono gli indici richiesti sono dolori.
  • Re: Subquery

    gibra ha scritto:


    Certo, ma a che pro? A mio avviso, in questo caso, nessuno.
    Ottieni solo il risultato di far lavorare molto di più il motore del database, e se per caso non vi sono gli indici richiesti sono dolori.
    Lo so, ma visto che mi sto esercitando e vorrei capire di quanto aumenta il costo usando le join o le subquery

    mi potresti aiutare a farla?
  • Re: Subquery

    CRTVLB ha scritto:


    mi potresti aiutare a farla?
    Intendi dire che non sai fare una subquery?
  • Re: Subquery

    Si,

    cioè le subquery le conosco ma non sono riuscito ad avere lo stesso risultato che mi restituisce la query.
  • Re: Subquery

    Perché le subquery sono più difficili da creare in quanto, diversamente dai join, devono portarsi dietro delle condizioni che nei join sono comuni.

    A parte questo, sconsiglio vivamente di fare join impliciti (come hai fatto tu) in quanto i risultati possono essere imprevedibili.
    Sempre meglio fare join espliciti, in cui si stabilisce esattamente ciò che si vuole.

    Detto questo, mostra i tuoi tentativi di subquery.
  • Re: Subquery

    Quello che dici è vero, ma io sto esercitandomi e sto cercando di capire la differenza di costi.

    sto procedendo per gradi, ho creato una subquery che mi restituisce id_cliente, id_fattura, tot_imponibile e data di tutte le fattura che contengono l'id_cliente che soddisfa determinate condizioni.
    SELECT 
    f.ID_CLIENTE,f.ID_FATTURA, f.TOTALE_IMPONIBILE, f.data
    FROM  fattura f
    where f.ID_cliente = (SELECT c.id_cliente from cliente c  where c.id_cliente = f.ID_CLIENTE 
    and f.id_fattura IN (select d.id_fattura from dett_fattura d where d.id_fattura = f.id_fattura and f.data BETWEEN to_date('01/01/2016', 'dd/mm/yyyy') AND to_date('11/11/2016', 'dd/mm/yyyy') 
    and d.QUANTITA_PRODOTTO > 3));
    poi ne ho creato un altra che mi restituisce l'id_cliente, la rag_soc e la partita iva
    SELECT 
    c.ID_CLIENTE,c.PARTITA_IVA,c.RAG_SOC
    FROM  cliente c
    where c.ID_cliente IN 
    (SELECT f.id_cliente from fattura f where f.id_cliente = c.ID_CLIENTE 
    and f.id_fattura IN (select d.id_fattura from dett_fattura d where d.id_fattura = f.id_fattura and f.data BETWEEN to_date('01/01/2016', 'dd/mm/yyyy') AND to_date('11/11/2016', 'dd/mm/yyyy')
    and d.QUANTITA_PRODOTTO > 3)) order by c.RAG_SOC;
    la prima mi restituisce 28 tuple, la seconda 5.

    I risultati sono esatti, poiché se inserisco una clausola distinct alla query con i join ho 28 risultati.

    Quello che non riesco a fare e "combinarle" per avere l'identico risultato che ottengo con la query con i join.

    Ho provato diversi metodi ma ho sempre l'errore too many values
  • Re: Subquery

    Se ottieni too many values è perché la subquery che usi dovrebbe restituire un solo valore, invece restituisce più righe.

    mostra come 'combini' le query
  • Re: Subquery

    Il problema è proprio che non riesco a combinarle.

    Ho fatto diverse prova, tutte non le ricordo ma la maggior parte mi restituiva sempre lo stesso errore

    l'ultima prova che ho fatto, sapendo già di sbagliare, è stata questa
    
    SELECT 
    f.ID_CLIENTE,f.ID_FATTURA, f.TOTALE_IMPONIBILE, f.data, c.id_cliente
    FROM  fattura f
    where f.ID_cliente = (SELECT c.id_cliente from cliente c  where c.id_cliente = f.ID_CLIENTE 
    and f.id_fattura IN (select d.id_fattura from dett_fattura d where d.id_fattura = f.id_fattura and f.data BETWEEN to_date('01/01/2016', 'dd/mm/yyyy') AND to_date('11/11/2016', 'dd/mm/yyyy') 
    and d.QUANTITA_PRODOTTO > 3) and c.ID_CLIENTE in (SELECT 
    c.ID_CLIENTE,c.PARTITA_IVA,c.RAG_SOC
    FROM  cliente c
    where c.ID_cliente IN 
    (SELECT f.id_cliente from fattura f where f.id_cliente = c.ID_CLIENTE 
    and f.id_fattura IN (select d.id_fattura from dett_fattura d where d.id_fattura = f.id_fattura and f.data BETWEEN to_date('01/01/2016', 'dd/mm/yyyy') AND to_date('11/11/2016', 'dd/mm/yyyy')
    and d.QUANTITA_PRODOTTO > 3))));
    
    Il risultato, come supponevo, è c.id_cliente indentificativo non valido.
  • Re: Subquery

    Prima di tutto, devi scrivere 'ordinato' altrimenti non si capisce nulla.
    Esempio:
    SELECT f.ID_CLIENTE,f.ID_FATTURA, f.TOTALE_IMPONIBILE, f.data, c.id_cliente
    FROM  fattura f
    WHERE f.ID_cliente = (
        SELECT c.id_cliente FROM cliente c  
        WHERE c.id_cliente = f.ID_CLIENTE AND f.id_fattura IN (
            SELECT d.id_fattura 
            FROM dett_fattura d 
            WHERE d.id_fattura = f.id_fattura 
            AND f.data BETWEEN TO_DATE('01/01/2016', 'dd/mm/yyyy') AND TO_DATE('11/11/2016', 'dd/mm/yyyy')
            AND d.QUANTITA_PRODOTTO > 3) 
    
            AND c.ID_CLIENTE IN (
                SELECT c.ID_CLIENTE,c.PARTITA_IVA,c.RAG_SOC
                FROM  cliente c
                WHERE c.ID_cliente IN (
                    SELECT f.id_cliente 
                    FROM fattura f 
                    WHERE f.id_cliente = c.ID_CLIENTE
                    AND f.id_fattura IN (
                        SELECT d.id_fattura 
                        FROM dett_fattura d 
                        WHERE d.id_fattura = f.id_fattura 
                        AND f.data BETWEEN TO_DATE('01/01/2016', 'dd/mm/yyyy') AND TO_DATE('11/11/2016', 'dd/mm/yyyy')
                        AND d.QUANTITA_PRODOTTO > 3))));
    Ora esaminiamo la query.
    L'errore che ricevi è perché la colonna c.id_cliente vuole che vi sia un JOIN tra la tabella Fatture e quella Cliente (*), cosa che in realtà non c'è.

    Inoltre, stai mescolando un po' troppi enunciati SQL inutilmente, non è questo il modo di usare le subquery.

    Non capisco questo tuo modo di procedere...
    Mi dici su quale testo/libro stai studiando le query?



    (*)Il nome della tabella Cliente è sbagliato, lo standard prevede l'uso del plurale, per cui il nome corretto è Clienti.
  • Re: Subquery

    In realtà sto cercando qualche buon libro, per il momento ho trovato solo articoli googlando un po'.

    Una cosa non mi è chiara, io vorrei ottenere lo stesso risultato della query del primo post senza usare nessun join, per vedere quanto cambia il costo usando le subquery invece di usare i join.

    è una cosa fattibile o no?
  • Re: Subquery

    Senza un buon libro non vai da nessuna parte.
    Non mi sono mai troppo affidato ad articoli sul web, nel senso che possono certamente essere utili per affrontare 'determinate' situazioni, ma a te che sei un neofita occorre prima conoscere la teoria dei database relazionali quindi ti occorre un libro che spieghi, con degli esempi, ecc.

    Ti ho già detto che si può fare, ma il costo è sempre maggiore di un JOIN esplicito.
Devi accedere o registrarti per scrivere nel forum
11 risposte