Domanda

Quando scrivo una query SQL, mi trovo spesso a pensare che "non c'è modo di fare questo con una singola query".Quando succede, mi capita spesso di girare per le stored procedure o multi-dichiarazione di funzioni con valori di tabella utilizzo di tabelle temporanee (di un tipo o di un altro) e finiscono semplicemente combinando i risultati e la restituzione della tabella dei risultati.

Mi chiedo se qualcuno lo sa, semplicemente come una questione di teoria, se dovrebbe essere possibile scrivere una query che restituisce un singolo set di risultati di una query (non più istruzioni).Ovviamente, sto ignorando punti di rilievo come la leggibilità del codice e la manutenibilità, forse anche le prestazioni delle query/efficienza.Questo è più di una teoria - può essere fatto...e non preoccuparti, io di certo non prevede di avviare costringendomi a scrivere una singola istruzione di query quando multi-dichiarazione di soddisfare meglio il mio scopo in tutti i casi, ma potrebbe farmi pensare due volte, o un po ' più a lungo se c'è una via praticabile per ottenere il risultato di una singola query.

Credo che alcuni parametri sono in ordine - sto pensando a un database relazionali (MS SQL) con tabelle che seguono le migliori pratiche comuni (come tutte le tabelle che hanno una chiave primaria, e così via).

Nota:per vincere 'Accettato di Rispondere' su questo, è necessario fornire una prova definitiva (riferimento a materiale per il web o qualcosa di simile.)

È stato utile?

Soluzione

Almeno con la una versione recente di Oracle è assolutamente possibile. Ha un 'clausola di modello' che rende sql Turing completo. ( http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/ ). Naturalmente questo è tutto con la solita limitazione che in realtà non abbiamo tempo illimitato e la memoria.

Per un dialetto SQL normale senza questi abdominations non credo sia possibile.

Un compito che non riesco a vedere come implementare in 'sql normale' sarebbe: Assumere una tabella con una singola colonna di tipo integer

Per ogni riga 'Prendere il valore alla riga corrente e andare che molte righe indietro, recuperare quel valore, andare che molte righe indietro, e continuare fino a procurarsi la stesso valore due volte consecutivamente e ritorni che come risultato.'

Altri suggerimenti

Credo che sia possibile. Ho lavorato con le query molto difficili, query molto lunghi, e spesso, è possibile farlo con una singola query. Ma la maggior parte del tempo, è più difficile da mantenere, quindi se lo si fa con una singola query, assicuratevi di commentare la query con attenzione.

Non ho mai incontrato qualcosa che non poteva essere fatto in una singola query.
Ma a volte è meglio farlo in più di una query.

Non posso provarlo, ma credo che la risposta è un sì prudente - fornito la struttura del database è fatto correttamente. Di solito viene costretto a scrivere più istruzioni per ottenere un certo risultato è un segno che lo schema può avere bisogno di alcuni miglioramenti.

Mi piacerebbe dire "sì", ma non può dimostrarlo.Tuttavia, il mio principale pensiero:

  • Ogni scelta deve essere un set di base di funzionamento

  • Il presupposto è che hai a che fare con matematicamente corretto imposta (cioè normalizzato correttamente)

  • Teoria dovrebbe garantire è possibile

Altri pensieri:

  • Più istruzione SELECT spesso carico di tabelle temporanee/variabili di tabella.Questi possono essere derivate o separati in Cte.

  • Qualsiasi elaborazione RBAR (bene o male) ora essere affrontato con CROSS/ESTERNO si APPLICA sulle tabelle derivate

  • Fsu sarebbe classificato come "barare" in questo contesto mi sento, perché permette di mettere una SELECT in un altro modulo, piuttosto che in uno

  • Non scrive ammessi nel "prima" sequenza di DML:questo cambia stato da SELEZIONARE per SELEZIONARE

  • Hai visto la parte del codice nel nostro negozio?

Modifica, glossario

Edit:APPLICARE:barare?

SELECT
    *
FROM
    MyTable1 t1
    CROSS APPLY
    (
        SELECT * FROM MyTable2 t2
        WHERE t1.something = t2.something
    ) t2

In teoria sì, se si utilizzano funzioni o un labirinto tortuoso di Outer applys o sub-query; Tuttavia, per migliorare la leggibilità e la performance, abbiamo sempre finito per andare con tabelle temporanee e stored procedure con più istruzioni.

Come qualcuno ha commentato in precedenza, questo di solito è un segno che la struttura di dati sta cominciando a sentire l'odore; Non che sia male , ma che forse è il momento di denormalise per motivi di prestazioni (succede al meglio di noi), o forse mettere uno strato di interrogazione denormalizzato davanti ai vostri dati normalizzati "reali".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top