2009-06-12 6 views
43

Esiste una sintassi di subquery SQL che consente di definire, letteralmente, una tabella temporanea?Puoi definire tabelle "letterali" in SQL?

Per esempio, qualcosa come

SELECT 
    MAX(count) AS max, 
    COUNT(*) AS count 
FROM 
    (
    (1 AS id, 7 AS count), 
    (2, 6), 
    (3, 13), 
    (4, 12), 
    (5, 9) 
) AS mytable 
    INNER JOIN someothertable ON someothertable.id=mytable.id 

Questo permetterebbe di risparmiare dover fare due o tre richieste: la creazione di tabella temporanea, mettendo i dati in esso, poi usarlo in un join.

Sto usando MySQL ma sarei interessato ad altri database che potrebbero fare qualcosa del genere.

risposta

42

Suppongo che potresti eseguire una subquery con più SELECT s in combinazione con UNION s.

SELECT a, b, c, d 
FROM (
    SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d 
    UNION ALL 
    SELECT 5 , 6, 7, 8 
) AS temp; 
+0

Wow, questa è una soluzione creativa! Sembra che almeno avrebbe funzionato. – thomasrutter

+0

Effettivamente, fa =) – Blixt

6

Ho trovato questo link Temporary Tables With MySQL

CREATE TEMPORARY TABLE TempTable (ID int, Name char(100)) TYPE=HEAP; 

INSERT INTO TempTable VALUES(1, "Foo bar"); 

SELECT * FROM TempTable; 

DROP TABLE TempTable; 
0

CREATE TEMPORARY TABLE (ID int, nome char (100)) SELECT ....

saperne di più su: http://dev.mysql.com/doc/refman/5.0/en/create-table.html

(vicino al fondo)

Questo ha il vantaggio che se c'è qualche problema che popola la tabella (mancata corrispondenza del tipo di dati) la tabella viene automaticamente eliminata.

Una risposta anticipata utilizzava una clausola FROM SELECT. Se possibile usalo perché risparmia il mal di testa della pulizia del tavolo.

Lo svantaggio (che potrebbe non essere importante) con FROM SELECT è la dimensione del set di dati creato. Una tabella temporanea consente l'indicizzazione che può essere critica. Per la query successiva. Sembra contro-intuitivo, ma anche con un set di dati di medie dimensioni (~ 1000 righe), può essere più veloce avere un indice creato per il funzionamento della query.

14

In SQL standard (SQL 2003 - vedi http://savage.net.au/SQL/) è possibile utilizzare:

INSERT INTO SomeTable(Id, Count) VALUES (1, 7), (2, 6), (3, 13), ... 

Con un po 'più a caccia, è anche possibile utilizzare:

SELECT * FROM TABLE(VALUES (1,7), (2, 6), (3, 13), ...) AS SomeTable(Id, Count) 

Sia questi lavori in MySQL è un problema separato - ma puoi sempre chiedere di ottenerlo aggiunto o aggiungerlo tu stesso (questa è la bellezza di Open Source).

+0

Grazie per la risposta! Purtroppo MySQL (5.0) non mi piace FROM TABLE (VALORI ... ma almeno lo so ora – thomasrutter

+0

Questa risposta è probabilmente più informativa della risposta accettata, ma non ha risolto il mio problema personale perché ero utilizzando MySQL. Vorrei poter accettare più risposte. – thomasrutter

+0

al contrario, il brutto Open Source è, chiedere verrà ignorato o rifiutato a meno che un sacco di persone e/o uno sviluppatore con tempo libero è interessato, e la curva di apprendimento per il fai da te è spesso proibitivo (per non dire che l'alternativa è in ogni caso migliore ...) – Michael

0

In una parola, sì. IMO ancora migliore se il tuo prodotto SQL supporta le espressioni di tabella comuni (CTE), cioè più facilmente sull'occhio che usando una subquery più lo stesso CTE può essere usato più volte, ad es. questo per 'creare' una tabella di sequenza di interi unici compresi tra 0 e 999 in SQL Server 2005 e sopra:

WITH Digits (nbr) AS 
(
SELECT 0 AS nbr UNION ALL SELECT 1 UNION ALL SELECT 2 
UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 
UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 
UNION ALL SELECT 9 
), 
Sequence (seq) AS 
(
SELECT Units.nbr + Tens.nbr + Hundreds.nbr 
    FROM Digits AS Units 
     CROSS JOIN Digits AS Tens 
     CROSS JOIN Digits AS Hundreds 
) 
SELECT S1.seq 
    FROM Sequence AS S1; 

tranne che ci si effettivamente fare qualcosa di utile con la tabella di sequenza per esempio analizzare i caratteri da una colonna VARCHAR in una tabella di base.

TUTTAVIA, se si utilizza questa tabella, che consiste solo di valori letterali, più volte o in più query, perché non renderla una tabella di base in primo luogo? Ogni database che utilizzo ha una tabella Sequence di numeri interi (in genere 100K righe) perché è così utile in generale.