web-dev-qa-db-fra.com

Pouvez-vous définir des tables "littérales" en SQL?

Existe-t-il une syntaxe de sous-requête SQL qui vous permet de définir, littéralement, une table temporaire?

Par exemple, quelque chose comme

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

Cela éviterait de devoir faire deux ou trois requêtes: créer une table temporaire, y placer des données, puis l'utiliser dans une jointure.

J'utilise MySQL, mais je serais intéressé par d'autres bases de données pouvant faire quelque chose comme ça.

48
thomasrutter

Je suppose que vous pourriez faire une sous-requête avec plusieurs SELECTs combinés avec UNIONs.

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;
49
Blixt

Vous pouvez le faire dans PostgreSQL:

=> select * from (values (1,7), (2,6), (3,13), (4,12), (5,9) ) x(id, count);
 id | count 
----+-------
  1 |     7
  2 |     6
  3 |    13
  4 |    12
  5 |     9

http://www.postgresql.org/docs/8.2/static/sql-values.html

21
dvv

En SQL standard (SQL 2003 - voir http://savage.net.au/SQL/ ), vous pouvez utiliser:

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

Avec un peu plus de chasse, vous pouvez également utiliser:

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

Que cela fonctionne dans MySQL est une question distincte - mais vous pouvez toujours demander de l'ajouter ou de l'ajouter vous-même (c'est la beauté de l'Open Source).

16
Jonathan Leffler

Dans Microsoft T-SQL 2008, le format est le suivant:

SELECT a, b FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b)

C'est à dire. comme Jonathan l'a mentionné ci-dessus, mais sans le mot clé "table".

Voir:

13
Pete

J'ai trouvé ce lien Tables temporaires avec 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;
6
ole6ka

CREATE TEMPORARY TABLE (ID int, Nom du caractère (100)) SELECT ....

En savoir plus sur: http://dev.mysql.com/doc/refman/5.0/en/create-table.html

(près du bas)

Cela présente l'avantage qu'en cas de problème de remplissage de la table (incompatibilité de type de données), la table est automatiquement supprimée.

Une réponse rapide utilisait une clause FROM SELECT. Si possible, utilisez-le car cela vous évitera des maux de tête liés au nettoyage de la table.

L’inconvénient (qui n’a pas d’importance) avec FROM SELECT est la taille du jeu de données créé. Une table temporaire permet une indexation qui peut être critique. Pour la requête suivante. Cela semble contre-intuitif, mais même avec un ensemble de données de taille moyenne (~ 1 000 lignes), il peut être plus rapide de créer un index pour que la requête soit opérationnelle.

0
Pat

En un mot, oui. Même meilleure OMI si votre produit SQL prend en charge les expressions de table communes (CTE), c'est-à-dire plus faciles à regarder que d'utiliser une sous-requête plus le même CTE peut être utilisé plusieurs fois, par exemple ceci pour "créer" une table de séquence d'entiers uniques compris entre 0 et 999 dans SQL Server 2005 et versions ultérieures:

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;

sauf que vous feriez réellement quelque chose d'utile avec le tableau Séquence, par exemple. analyser les caractères d'une colonne VARCHAR dans une table de base.

CEPENDANT, si vous utilisez cette table, qui consiste uniquement en valeurs littérales, en plusieurs fois ou en plusieurs requêtes, pourquoi ne pas en faire une table de base? Chaque base de données que j'utilise possède une table de séquence d'entiers (généralement 100 000 lignes), car elle est très utile en général.

0
onedaywhen