Esiste una regola empirica per build una query SQL da una descrizione leggibile dall’uomo?

Ogni volta che c’è una descrizione della query di fronte a noi, cerchiamo di applicare l’euristica e il brainstorming per build la query.

Esiste un metodo passo-passo o matematico sistematico per build una query SQL da una descrizione umana leggibile?

Ad esempio, come determinare che, se una query SQL richiederebbe un join piuttosto che una sottoquery, se richiederebbe un gruppo, se richiederebbe una clausola IN, ecc ….

Ad esempio, chiunque abbia studiato Digital Electronics sarebbe a conoscenza dei metodi come Karnaugh Map o Quin McClausky. Questi sono alcuni approcci sistematici per semplificare la logica digitale.

Se esiste un metodo come questo per analizzare manualmente le query SQL per evitare il brainstorming ogni volta?

Esiste un metodo passo-passo o matematico sistematico per build una query SQL da una descrizione umana leggibile?

Si C’è.

Si scopre che le espressioni del linguaggio naturale e le espressioni logiche e le espressioni algebriche relazionali e le espressioni SQL (un ibrido degli ultimi due) corrispondono in modo piuttosto diretto.

Ogni tabella (base o risultato della query) ha un predicato associato – un modello di dichiarazione degli spazi vuoti compilato con il linguaggio naturale (denominato-), parametrizzato dai nomi delle colonne.

 -- person [liker] likes person [liked] 

Una tabella contiene ogni riga che, usando i valori della colonna della riga per riempire gli spazi vuoti (nominati), crea una vera affermazione alias proposizione .

 liker | liked -------------- Bob | Dex -- Bob likes Dex Bob | Alice -- Bob likes Alice Alice | Carol -- Alice likes Carol 

Ogni proposizione dal riempimento di un predicato con i valori di una riga in una tabella è vera. E ogni proposizione dal riempire un predicato con i valori di una riga non in una tabella è falsa.

 /* Alice likes Carol AND NOT Alice likes Alice AND NOT Alice likes Bob AND NOT Alice likes Dex AND NOT Alice likes Ed ... AND Bob likes Alice AND Bob likes Dex AND NOT Bob likes Bob AND NOT Bob likes Carol AND NOT Bob likes Ed ... AND NOT Carol likes Alice ... AND NOT Dex likes Alice ... AND NOT Ed likes Alice ... */ 

Il DBA fornisce il predicato per ciascuna tabella di base. La syntax SQL per una dichiarazione di tabella è molto simile alla tradizionale stenografia della logica per la versione in linguaggio naturale di un determinato predicato.

 -- person [liker] likes person [liked] -- Likes(liker, liked) SELECT * FROM Likes 

Un’espressione SQL (sub) expression trasforma i valori della tabella degli argomenti in un nuovo valore di tabella che contiene le righe che costituiscono una dichiarazione vera da un nuovo predicato. Il predicato della nuova tabella può essere express in termini di predicato della tabella degli argomenti in base agli operatori di tabella / relazionali dell’espressione (sub). Scriviamo un’espressione SQL il cui predicato è il predicato per la tabella che vogliamo.

All’interno di un’istruzione SELECT , quando una tabella di base T con colonne C,... ha un alias (forse implicito) A possiamo trattare A come una tabella con il valore di T ma con le colonne rinominate in AC,... (Possiamo usare C per AC quando non è ambiguo.) Quindi il predicato di una tabella di base chiamata T con alias A è T(AC,...) . Il predicato di R CROSS JOIN S o R INNER JOIN S è il predicato di R AND ed con il predicato di S Il predicato di R ON/WHERE condition è il predicato di R AND ed a condition . Il predicato di (...) IN R è R(...) . Una clausola SELECT DISTINCT che elenca le columns to keep una tabella mette le columns to drop FOR SOME o THERE EXISTS columns to drop prima del suo predicato. (Queste colonne non sono parametri del predicato risultante.) Una clausola SELECT che rinomina una colonna di una tabella (magari con A. implicita) tramite AS rinomina un nome nel suo predicato. (Questo rimuove A. s.)

 /* rows that make a true statement from FOR SOME l1.liked, l2.liker: Likes(person, l1.liked) AND Likes(l2.liker, liked) AND l1.liked = l2.liker AND person = 'Bob' AND NOT Likes(person, 'Ed') */ SELECT l1.liker AS person, l2.liked AS liked FROM /* rows that make a true statement from Likes(l1.liker, l1.liked) AND Likes(l2.liker, l2.liker) AND l1.liked = l2.liker AND l1.liker = 'Bob' AND NOT Likes(l1.liker, 'Ed') */ Likes l1 INNER JOIN Likes l2 ON l1.liked = l2.liker WHERE l1.liker = 'Bob' AND NOT (l1.liker, 'Ed') IN (SELECT * FROM Liker) 

Il predicato di R UNION CORRESPONDING S è il predicato di R OR ed il predicato di S Per R EXCEPT S , usiamo AND NOT . VALUES(C,...)((V,...),...) ha predicato (C = V AND ...) OR ...

 /* rows that make a true statement from FOR SOME liked, Likes(person, liked) OR person = 'Bob' */ SELECT liker AS person FROM Likes UNION VALUES (person) (('Bob')) 

Quindi, se esprimiamo le nostre righe desiderate in termini di modelli di statement linguistici della tabella di base forniti che le righe rendono true o false (da restituire o meno), possiamo tradurre query SQL che sono nidificazioni di combinazioni di tasti logici e operatori e / o nomi di tabelle e operatori. E poi il DBMS può convertire totalmente in tabelle per calcolare le righe rendendo il nostro predicato vero.

Vedi questo applicando questo a SQL e questo per ulteriori informazioni sulle frasi in linguaggio naturale.

Ecco cosa faccio nelle query non raggruppate:

Inserisco nella clausola FROM la tabella di cui prevedo di ricevere zero o una riga di output per riga nella tabella. Spesso, vuoi qualcosa come “tutti i clienti con determinate proprietà”. Quindi, la tabella del cliente entra nella clausola FROM .

Utilizza i join per aggiungere colonne e filtrare le righe. I join non dovrebbero duplicare le righe. Un join dovrebbe trovare zero o una riga, mai più. Ciò lo rende molto intuitivo perché puoi dire che “un join aggiunge colonne e filtra alcune righe”.

Le sottoquery devono essere evitate se un join può sostituirle. I join hanno un aspetto più gradevole, sono più generali e spesso sono più efficienti (a causa dei comuni punti deboli dell’ottimizzatore delle query).

Come usare WHERE e le proiezioni sono facili.