Existe-t-il un moyen d’ SELECT
afficher toutes les colonnes d’un tableau, à l’exception de celles spécifiques? C’est très pratique pour sélectionner toutes les colonnes non géométriques ou non géométriques d’un tableau.
Quelque chose comme:
SELECT * -the_geom FROM segments;
- Une fois, j'ai entendu dire que cette fonctionnalité avait été délibérément exclue du standard SQL, car le fait d'ajouter des colonnes à la table modifierait les résultats de la requête. Est-ce vrai? L'argument est-il valide?
- Existe-t-il une solution de contournement, en particulier dans PostgreSQL?
postgresql
sql-standard
Adam Matan
la source
la source
name
,age
,sid
) qui convient bien dans la largeur de l' écran, alongwith une longue binairegeom
colonne. Je veux interroger tous les champs sauf le binaire géométrie, et écrire leurs noms un par un est fastidieux.select (!coluns2,!column5) from sometable;
Réponses:
Une telle fonctionnalité n'existe ni dans Postgres ni dans SQL Standard (autant que je sache). Je pense que c'est une question assez intéressante, alors j'ai googlé un peu et je suis tombé sur un article intéressant sur postgresonline.com .
Ils montrent une approche qui sélectionne les colonnes directement à partir du schéma:
Vous pouvez créer une fonction qui fait quelque chose comme ça. Ces sujets ont également été abordés sur les listes de diffusion, mais le consensus général était à peu près le même: interroger le schéma.
Je suis sûr qu'il existe d'autres solutions, mais je pense qu'elles impliqueront toutes une sorte de schéma-queriying-foo magique.
BTW: Soyez prudent avec
SELECT * ...
car cela peut avoir des pénalités de performancela source
La vraie réponse est que vous ne pouvez pas pratiquement. Cette fonctionnalité est demandée depuis des décennies et les développeurs refusent de la mettre en œuvre.
La réponse courante suggérant d'interroger les tables de schéma ne pourra pas s'exécuter efficacement car l'optimiseur Postgres considère les fonctions dynamiques comme une boîte noire (voir le cas de test ci-dessous). Cela signifie que les index ne seront pas utilisés et les jointures ne se feront pas de manière intelligente. Vous seriez beaucoup mieux avec une sorte de système macro tel que m4. Au moins, cela ne confondra pas l'optimiseur (mais cela peut encore vous dérouter). Sans forger le code et écrire la fonctionnalité vous-même ou en utilisant une interface de langage de programmation, vous êtes bloqué.
J'ai écrit ci-dessous une simple démonstration de faisabilité montrant la mauvaise performance d'une exécution dynamique très simple dans plpgsql. Notez également que ci-dessous je dois contraindre une fonction renvoyant un enregistrement générique dans un type de ligne spécifique et énumérer les colonnes. Donc, cette méthode ne fonctionnera pas pour 'tout sélectionner sauf' sauf si vous voulez refaire cette fonction pour toutes vos tables.
Comme vous pouvez le voir, l'appel de fonction a balayé la totalité de la table alors que la requête directe utilisait l'index ( 95,46 ms par rapport à 00,07ms .) .
la source
En fait, c'est un peu possible avec PostgreSQL à partir de la version 9.4 où JSONB a été introduit. Je réfléchissais à une question similaire sur la façon d'afficher tous les attributs disponibles dans Google Map (via GeoJSON).
johto sur le canal irc a suggéré d'essayer de supprimer un élément de JSONB.
Voici l'idée
Bien que vous obteniez JSON au lieu de colonnes individuelles, c’était exactement ce que je voulais. Peut-être que json peut être reconverti en colonnes individuelles.
la source
La seule façon de le faire (ne pas dire que vous devriez) est d'utiliser des instructions SQL dynamiques. Il est facile (comme l'a écrit DrColossos) d'interroger les vues système, de trouver la structure de la table et de construire les instructions appropriées.
PS: Pourquoi voudriez-vous sélectionner toutes / certaines colonnes sans connaître / écrire exactement la structure de votre table?
la source
Dynamiquement, comme indiqué ci-dessus, c'est la seule réponse mais je ne le recommanderai pas. Que faire si vous ajoutez plus de colonnes sur le long terme mais qu'elles ne sont pas nécessairement requises pour cette requête?
Vous commenceriez à tirer plus de colonne que nécessaire.
Que faire si la sélection fait partie d'un insert comme dans
Insérer dans la tableA (col1, col2, col3 .. coln) Sélectionnez tout sauf 2 colonnes FROM tableB
La correspondance de colonne sera fausse et votre insertion échouera.
C'est possible, mais je recommande quand même d'écrire chaque colonne nécessaire pour chaque sélection écrite, même si presque chaque colonne est requise.
la source
SELECT
s.Si votre objectif est de supprimer l'encombrement de l'écran lors du débogage en n'affichant pas les colonnes contenant des valeurs de données volumineuses, vous pouvez utiliser le truc suivant:
(installez le paquet contrib "hstore" si vous ne l'avez pas déjà: "
CREATE EXTENSION hstore;
")Pour une table "test" avec col1, col2, col3, vous pouvez définir la valeur de "col2" sur null avant d'afficher:
Ou définissez deux colonnes sur null avant d'afficher:
les mises en garde sont que "test" doit être une table (un alias ou un sous-choix ne fonctionnera pas) car le type d'enregistrement alimentant hstore doit être défini.
la source
Il existe une solution de contournement que je viens de découvrir, mais elle nécessite l'envoi de requêtes SQL depuis R. Elle peut être utile aux utilisateurs de R.
En gros, le
dplyr
paquet envoie des requêtes SQL (et plus particulièrement PostgreSQL) et accepte l'-(column_name)
argument.Donc, votre exemple pourrait être écrit comme suit:
la source
Dans un commentaire, vous expliquez que votre motif est d'avoir la commodité de ne pas afficher le contenu des colonnes à long contenu, plutôt que de ne pas afficher la colonne elle-même:
Cela est possible, à l'aide d'une fonction d'assistance qui remplace le contenu long par
null
(n'importe quelletext
colonne de mon exemple, mais que vous modifieriez pour les types que vous souhaitez supprimer):dbfiddle ici
la source
Du point de vue de l'application, il s'agit d'une solution paresseuse. Il est peu probable qu'une application sache automatiquement quoi faire avec la ou les nouvelles colonnes.
Les applications de navigateur de données peuvent interroger les métadonnées pour les données et exclure les colonnes des requêtes en cours d'exécution ou sélectionner un sous-ensemble des données de la colonne. Les nouveaux BLOBs peuvent être exclus une fois ajoutés. Les données BLOB pour des lignes particulières peuvent être sélectionnées à la demande.
Dans toute variante SQL prenant en charge les requêtes dynamiques, la requête peut être générée à l'aide d'une requête sur les métadonnées des tables. Pour votre intention, j'exclurais les colonnes basées sur le type plutôt que sur le nom.
la source
Vous ne voyez jamais
*
dans SQL-VIEWS ... vérifiez\d any_view
à votrepsql
. Il existe un prétraitement (introspectif) pour la représentation interne.Toutes les discussions ici montrent que la proposition de problème (implicite dans la question et les discussions) est un sucre de syntaxe pour les programmeurs, pas un vrai "problème d'optimisation SQL" ... Eh bien, je suppose que cela concerne 80% des programmeurs.
Donc, peut être implémenté comme " pré-analyse avec introspection" ... Voyez ce que fait PostgreSQL lorsque vous déclarez une vue SQL-VIEW avec
SELECT *
: le constructeur VIEW se transforme*
en une liste de toutes les colonnes (par introspection et au moment où vous exécutez le CREATE VIEW code source).Implémentation pour CREATE VIEW et PREPARE
C'est une implémentation viable. Supposons une table
t
avec des champs(id serial, name text, the_geom geom)
.Idem pour l' instruction PREPARE .
... donc, c'est possible, et c'est ce dont ont besoin 80% des programmeurs, un sucre de syntaxe pour PREPARE et VIEWS!
NOTE: Bien sûr, la syntaxe viable n'est peut-être pas
- column_name
, s'il y a un conflit dans PostgreSQL, nous pouvons donc suggérerEXCEPT column_name
,EXCEPT (column_name1, column_name2, ..., column_nameN)
ou autre.la source
Ceci est ma fonction pour sélectionner toutes les colonnes en attendre une. J'ai combiné des idées de postgresonline.com et de postgresql tuturial et d'autres sources.
la source