CRÉER UN TABLEAU COMME SÉLECTIONNER DANS

16

PostgreSQL prend en charge CREATE TABLE ASet SELECT INTOquand dois-je utiliser les deux?

CREATE TABLE AS - définir une nouvelle table à partir des résultats d'une requête

CREATE TABLE AScrée une table et la remplit de données calculées par une SELECTcommande. Les colonnes de table ont les noms et les types de données associés aux colonnes de sortie de SELECT(sauf que vous pouvez remplacer les noms de colonne en donnant une liste explicite de nouveaux noms de colonne).

CREATE TABLE ASressemble à la création d'une vue, mais c'est vraiment très différent: il crée une nouvelle table et évalue la requête une seule fois pour remplir la nouvelle table initialement. La nouvelle table ne suivra pas les modifications ultérieures apportées aux tables source de la requête. En revanche, une vue réévalue sa SELECTdéclaration de définition chaque fois qu'elle est interrogée.

Puis.

SELECT INTO - définir une nouvelle table à partir des résultats d'une requête

SELECT INTOcrée une nouvelle table et la remplit de données calculées par une requête. Les données ne sont pas retournées au client, comme c'est le cas avec une normale SELECT. Les colonnes de la nouvelle table ont les noms et les types de données associés aux colonnes de sortie de SELECT.

Evan Carroll
la source

Réponses:

15

Sans explication, utilisez toujours CREATE TABLE ASsans exception. Au bas de chaque sous NOTES, ceci est effacé,

Notes pour SELECT INTO,

CREATE TABLE ASest fonctionnellement similaire à SELECT INTO. CREATE TABLE ASest la syntaxe recommandée, car cette forme de SELECT INTOn'est pas disponible dans ECPG ou PL / pgSQL, car ils interprètent la clause INTO différemment. En outre, CREATE TABLE ASoffre un surensemble des fonctionnalités fournies par SELECT INTO.

Notes pour CREATE TABLE AS,

Cette commande est fonctionnellement similaire à SELECT INTO, mais elle est préférée car elle est moins susceptible d'être confondue avec d'autres utilisations de la SELECT INTOsyntaxe. En outre, CREATE TABLE ASoffre un surensemble des fonctionnalités offertes par SELECT INTO.

Toujours dans la section Compatibilité de la documentation, SELECT INTOil va encore plus loin,

Le standard SQL utilise SELECT INTOpour représenter la sélection des valeurs dans les variables scalaires d'un programme hôte, plutôt que de créer une nouvelle table. C'est en effet l'usage trouvé dans ECPG (voir chapitre 34) et PL / pgSQL (voir chapitre 41). L'utilisation de PostgreSQL SELECT INTOpour représenter la création d'une table est historique. Il est préférable d'utiliser CREATE TABLE ASà cet effet dans le nouveau code.

Nous avons donc,

  1. PostgreSQL pense que c'est déroutant car il SELECT INTOfait d'autres choses dans des contextes uniquement disponibles en PL / pgSQL et ECPG.
  2. CREATE TABLEprend en charge plus de fonctionnalités (je suppose qu'ils font référence à WITH OIDS, et TABLESPACE, IF NOT EXISTS).
  3. SELECT INTO pour la création de table est "obsolète".

En remarque, la syntaxe d'un CTAS avec un CTE peut sembler un peu bizarre. , et SELECT INTO peut également être une sorte de prise sur les QUELRETRIEVE INTO . QUEL était le prédécesseur de SQL, que le prédécesseur de PostgreSQL (INGRES) utilisait.

Evan Carroll
la source
1

Il y a une autre chose que j'ai remarqué qui manque dans la réponse acceptée. L'utilisation CREATE TABLE ASpréserve l'attribut nullable de chaque colonne qui semble être ignoré par SELECT INTO.

Rien que sur cette base, je recommanderais CREATE TABLE AS. Un cas d'utilisation courant pour les deux instructions consiste à charger les données d'une requête de longue durée dans une table sans verrouiller cette table pendant la durée de votre requête. Vous créez une table temporaire à l'aide de l'une des commandes ci-dessus, placez-y les résultats de la requête longue, puis insérez ces résultats dans la table d'origine. La conservation de l'attribut nullable dans votre table temporaire réduit les risques d'échec de votre deuxième insertion.

Testé sur PG 11, donc peut-être une fonctionnalité plus récente depuis la réponse à cette question.

Shrumm
la source
Une requête longue ne verrouille aucune table. Donc, la motivation pour utiliser CTAS pour cette raison est futile
a_horse_with_no_name