SQL select join: est-il possible de préfixer toutes les colonnes par un préfixe'.*'?

je me demande si C'est possible en SQL. Supposons que vous ayez deux tableaux A et B, et que vous faites un choix sur le tableau A et que vous vous joignez au tableau B:

SELECT a.*, b.* FROM TABLE_A a JOIN TABLE_B b USING (some_id);

Si la table a des colonnes a_id', 'nom', et 'some_id', et le tableau B a 'b_id', 'nom', et 'some_id', la requête retourne les colonnes 'a_id', 'nom', 'some_id', 'b_id', 'nom', 'some_id'. Y a-t-il un moyen de préfixer les noms de colonne du tableau B sans énumérer chaque colonne individuellement? L'équivalent de ce:

SELECT a.*, b.b_id as 'b.b_id', b.name as 'b.name', b.some_id as 'b.some_id'
FROM TABLE_A a JOIN TABLE_B b USING (some_id);

mais, comme mentionné, sans énumérer chaque colonne, donc quelque chose comme:

SELECT a.*, b.* as 'b.*'
FROM TABLE_A a JOIN TABLE_B b USING (some_id);

essentiellement quelque chose à dire, " préfixe chaque colonne retournée par B.* avec "quelque chose". Est-ce possible ou est-ce que je n'ai pas de chance?

Merci d'avance pour votre aide!

EDIT: Conseil de ne pas utiliser SELECT * et ainsi de suite est un conseil valable mais non pertinent dans mon contexte, alors s'il vous plaît s'en tenir au problème en question -- Est il est possible d'ajouter un préfixe (une constante spécifiée dans la requête SQL) pour tous les noms de colonnes d'une table dans une jointure?

EDIT: mon but ultime est de pouvoir faire un SELECT * sur deux tables avec une jointure, et être capable de dire, à partir des noms des colonnes que j'obtiens dans mon jeu de résultats, quelles colonnes viennent du tableau A et quelles colonnes viennent du tableau B. encore une fois, je ne veux pas avoir à énumérer les colonnes individuellement, je dois être en mesure de faire un SELECT *.

157
demandé sur mwigdahl 2008-12-01 06:15:58

19 réponses

je vois deux situations possibles ici. Tout d'abord, vous voulez savoir s'il existe une norme SQL pour cela, que vous pouvez utiliser en général indépendamment de la base de données. Non, il n'est pas. Deuxièmement, vous voulez savoir en ce qui concerne un produit de SGBD spécifique. Ensuite, vous devez l'identifier. Mais j'imagine que la réponse la plus probable est que vous allez récupérer quelque chose comme "A. id, B. id " puisque c'est comme ça que vous devez identifier les colonnes dans votre expression SQL. Et la façon la plus facile de trouver ce qu'est la valeur par défaut, c'est juste pour présenter une telle requête et voir ce que vous obtenez en retour. Si vous voulez spécifier quel préfixe vient avant le point, vous pouvez utiliser "SELECT * FROM a AS my_alias", par exemple.

34
répondu dkretz 2011-12-22 17:32:07

il semble que la réponse à votre question est non, mais un piratage que vous pouvez utiliser est d'assigner une colonne factice pour séparer chaque nouvelle table. Cela fonctionne particulièrement bien si vous êtes en boucle à travers un jeu de résultats pour une liste de colonnes dans un langage de script tel que Python ou PHP.

SELECT '' as table1_dummy, table1.*, '' as table2_dummy, table2.*, '' as table3_dummy, table3.* FROM table1
JOIN table2 ON table2.table1id = table1.id
JOIN table3 ON table3.table1id = table1.id

je me rends compte que cela ne répond pas exactement à votre question, mais si vous êtes un codeur, c'est une excellente façon de séparer les tables avec des noms de colonne dupliqués. Espérons que cela aide quelqu'un.

50
répondu Wayne Bryan 2012-08-07 14:38:38

je comprends tout à fait pourquoi cela est nécessaire - au moins pour moi, il est pratique lors du prototypage rapide quand il ya beaucoup de tables nécessaires pour être joint, y compris de nombreuses jointures internes. Dès qu'un nom de colonne est la même pour une seconde "joinedtable.* "field wild card, les valeurs de champ de la table principale sont remplacées par les valeurs joinedtable. Sujet aux erreurs, frustrant et une violation de DRY lorsqu'il faut spécifier manuellement les champs de la table avec des Alias et des aliases...

Voici une fonction PHP (Wordpress) pour y parvenir à travers la génération de code ainsi qu'un exemple de la façon de l'utiliser. Dans l'exemple, il est utilisé pour générer rapidement une requête personnalisée qui fournira les champs d'un article wordpress lié qui a été référencé à travers un champ advanced custom fields .

function prefixed_table_fields_wildcard($table, $alias)
{
    global $wpdb;
    $columns = $wpdb->get_results("SHOW COLUMNS FROM $table", ARRAY_A);

    $field_names = array();
    foreach ($columns as $column)
    {
        $field_names[] = $column["Field"];
    }
    $prefixed = array();
    foreach ($field_names as $field_name)
    {
        $prefixed[] = "`{$alias}`.`{$field_name}` AS `{$alias}.{$field_name}`";
    }

    return implode(", ", $prefixed);
}

function test_prefixed_table_fields_wildcard()
{
    global $wpdb;

    $query = "
    SELECT
        " . prefixed_table_fields_wildcard($wpdb->posts, 'campaigns') . ",
        " . prefixed_table_fields_wildcard($wpdb->posts, 'venues') . "
        FROM $wpdb->posts AS campaigns
    LEFT JOIN $wpdb->postmeta meta1 ON (meta1.meta_key = 'venue' AND campaigns.ID = meta1.post_id)
    LEFT JOIN $wpdb->posts venues ON (venues.post_status = 'publish' AND venues.post_type = 'venue' AND venues.ID = meta1.meta_value)
    WHERE 1
    AND campaigns.post_status = 'publish'
    AND campaigns.post_type = 'campaign'
    LIMIT 1
    ";

    echo "<pre>$query</pre>";

    $posts = $wpdb->get_results($query, OBJECT);

    echo "<pre>";
    print_r($posts);
    echo "</pre>";
}

La sortie:

SELECT
    `campaigns`.`ID` AS `campaigns.ID`, `campaigns`.`post_author` AS `campaigns.post_author`, `campaigns`.`post_date` AS `campaigns.post_date`, `campaigns`.`post_date_gmt` AS `campaigns.post_date_gmt`, `campaigns`.`post_content` AS `campaigns.post_content`, `campaigns`.`post_title` AS `campaigns.post_title`, `campaigns`.`post_excerpt` AS `campaigns.post_excerpt`, `campaigns`.`post_status` AS `campaigns.post_status`, `campaigns`.`comment_status` AS `campaigns.comment_status`, `campaigns`.`ping_status` AS `campaigns.ping_status`, `campaigns`.`post_password` AS `campaigns.post_password`, `campaigns`.`post_name` AS `campaigns.post_name`, `campaigns`.`to_ping` AS `campaigns.to_ping`, `campaigns`.`pinged` AS `campaigns.pinged`, `campaigns`.`post_modified` AS `campaigns.post_modified`, `campaigns`.`post_modified_gmt` AS `campaigns.post_modified_gmt`, `campaigns`.`post_content_filtered` AS `campaigns.post_content_filtered`, `campaigns`.`post_parent` AS `campaigns.post_parent`, `campaigns`.`guid` AS `campaigns.guid`, `campaigns`.`menu_order` AS `campaigns.menu_order`, `campaigns`.`post_type` AS `campaigns.post_type`, `campaigns`.`post_mime_type` AS `campaigns.post_mime_type`, `campaigns`.`comment_count` AS `campaigns.comment_count`,
    `venues`.`ID` AS `venues.ID`, `venues`.`post_author` AS `venues.post_author`, `venues`.`post_date` AS `venues.post_date`, `venues`.`post_date_gmt` AS `venues.post_date_gmt`, `venues`.`post_content` AS `venues.post_content`, `venues`.`post_title` AS `venues.post_title`, `venues`.`post_excerpt` AS `venues.post_excerpt`, `venues`.`post_status` AS `venues.post_status`, `venues`.`comment_status` AS `venues.comment_status`, `venues`.`ping_status` AS `venues.ping_status`, `venues`.`post_password` AS `venues.post_password`, `venues`.`post_name` AS `venues.post_name`, `venues`.`to_ping` AS `venues.to_ping`, `venues`.`pinged` AS `venues.pinged`, `venues`.`post_modified` AS `venues.post_modified`, `venues`.`post_modified_gmt` AS `venues.post_modified_gmt`, `venues`.`post_content_filtered` AS `venues.post_content_filtered`, `venues`.`post_parent` AS `venues.post_parent`, `venues`.`guid` AS `venues.guid`, `venues`.`menu_order` AS `venues.menu_order`, `venues`.`post_type` AS `venues.post_type`, `venues`.`post_mime_type` AS `venues.post_mime_type`, `venues`.`comment_count` AS `venues.comment_count`
    FROM wp_posts AS campaigns
LEFT JOIN wp_postmeta meta1 ON (meta1.meta_key = 'venue' AND campaigns.ID = meta1.post_id)
LEFT JOIN wp_posts venues ON (venues.post_status = 'publish' AND venues.post_type = 'venue' AND venues.ID = meta1.meta_value)
WHERE 1
AND campaigns.post_status = 'publish'
AND campaigns.post_type = 'campaign'
LIMIT 1

Array
(
    [0] => stdClass Object
        (
            [campaigns.ID] => 33
            [campaigns.post_author] => 2
            [campaigns.post_date] => 2012-01-16 19:19:10
            [campaigns.post_date_gmt] => 2012-01-16 19:19:10
            [campaigns.post_content] => Lorem ipsum
            [campaigns.post_title] => Lorem ipsum
            [campaigns.post_excerpt] => 
            [campaigns.post_status] => publish
            [campaigns.comment_status] => closed
            [campaigns.ping_status] => closed
            [campaigns.post_password] => 
            [campaigns.post_name] => lorem-ipsum
            [campaigns.to_ping] => 
            [campaigns.pinged] => 
            [campaigns.post_modified] => 2012-01-16 21:01:55
            [campaigns.post_modified_gmt] => 2012-01-16 21:01:55
            [campaigns.post_content_filtered] => 
            [campaigns.post_parent] => 0
            [campaigns.guid] => http://example.com/?p=33
            [campaigns.menu_order] => 0
            [campaigns.post_type] => campaign
            [campaigns.post_mime_type] => 
            [campaigns.comment_count] => 0
            [venues.ID] => 84
            [venues.post_author] => 2
            [venues.post_date] => 2012-01-16 20:12:05
            [venues.post_date_gmt] => 2012-01-16 20:12:05
            [venues.post_content] => Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
            [venues.post_title] => Lorem ipsum venue
            [venues.post_excerpt] => 
            [venues.post_status] => publish
            [venues.comment_status] => closed
            [venues.ping_status] => closed
            [venues.post_password] => 
            [venues.post_name] => lorem-ipsum-venue
            [venues.to_ping] => 
            [venues.pinged] => 
            [venues.post_modified] => 2012-01-16 20:53:37
            [venues.post_modified_gmt] => 2012-01-16 20:53:37
            [venues.post_content_filtered] => 
            [venues.post_parent] => 0
            [venues.guid] => http://example.com/?p=84
            [venues.menu_order] => 0
            [venues.post_type] => venue
            [venues.post_mime_type] => 
            [venues.comment_count] => 0
        )
)
17
répondu Motin 2012-01-19 16:17:05

la seule base de données que je connaisse qui fait cela est SQLite, en fonction des paramètres que vous configurez avec PRAGMA full_column_names et PRAGMA short_column_names . Voir http://www.sqlite.org/pragma.html

sinon tout ce que je peux recommander est de récupérer des colonnes dans un résultat défini par la position ordinale plutôt que par le nom de la colonne, si c'est trop difficile pour vous de taper les noms des colonnes dans votre requête.

C'est un bon exemple de pourquoi c'est une mauvaise pratique d'utiliser SELECT * -- parce que finalement vous aurez besoin de taper tous les noms de colonne de toute façon.

je comprends la nécessité de supporter des colonnes qui peuvent changer de nom ou de position, mais utiliser des caractères génériques rend plus difficile , pas plus facile.

9
répondu Bill Karwin 2017-05-23 12:34:59

différents produits de base de données vous donnera des réponses différentes, mais vous vous préparez pour hurt si vous portez cette très loin. Vous êtes beaucoup mieux de choisir les colonnes que vous voulez, et leur donner vos propres alias afin que l'identité de chaque colonne est cristalline, et vous pouvez les distinguer dans les résultats.

5
répondu dkretz 2008-12-01 03:19:07

je suis en quelque sorte dans le même bateau que OP - j'ai des douzaines de champs de 3 tables différentes que je joins, dont certaines ont le même nom(c.-à-d. id, nom, etc). Je ne veux pas énumérer chaque champ, donc ma solution était d'alias les champs qui partageaient un nom et d'utiliser select * pour ceux qui avaient un nom unique.

par exemple:

tableau a : ID, nom, champ1, champ2 ...

tableau b : ID, nom, field3, field4 ...

sélectionner a. id as aID, A. nom comme aName, A. * , B. id as bID, B. nom en tant que nom B, B. * .....

lors de l'accès aux résultats, j'utilise les noms d'Alias pour ces champs et ignore les noms "originaux".

Peut-être pas la meilleure solution mais ça marche pour moi....j'utilise mysql

5
répondu 2008-12-02 14:06:34

Cette question est très utile dans la pratique. Il est seulement nécessaire d'énumérer toutes les colonnes explicites dans la programmation de logiciel, où vous payez particulièrement prudent de traiter avec toutes les conditions.

imaginez lors du débogage, ou, essayez D'utiliser des SGBD comme outil de bureau quotidien, au lieu de quelque chose d'implémentation modifiable de l'infrastructure abstraite sous-jacente du programmeur spécifique, nous avons besoin de coder beaucoup de SQL. Le scénario peut être trouvé partout, comme la conversion de base de données, migration, administration, etc. La plupart de ces SQL ne seront exécutés qu'une seule fois et ne seront plus jamais utilisés, donner le nom de chaque colonne est une perte de temps. Et n'oubliez pas que L'invention de SQL n'est pas seulement destinée aux programmeurs.

Habituellement je vais créer une vue utilitaire avec des noms de colonne préfixés, voici la fonction dans pl/pgsql, ce n'est pas facile, mais vous pouvez la convertir à d'autres langues de procédure.

-- Create alias-view for specific table.

create or replace function mkaview(schema varchar, tab varchar, prefix varchar)
    returns table(orig varchar, alias varchar) as $$
declare
    qtab varchar;
    qview varchar;
    qcol varchar;
    qacol varchar;
    v record;
    sql varchar;
    len int;
begin
    qtab := '"' || schema || '"."' || tab || '"';
    qview := '"' || schema || '"."av' || prefix || tab || '"';
    sql := 'create view ' || qview || ' as select';

    for v in select * from information_schema.columns
            where table_schema = schema and table_name = tab
    loop
        qcol := '"' || v.column_name || '"';
        qacol := '"' || prefix || v.column_name || '"';

        sql := sql || ' ' || qcol || ' as ' || qacol;
        sql := sql || ', ';

        return query select qcol::varchar, qacol::varchar;
    end loop;

    len := length(sql);
    sql := left(sql, len - 2); -- trim the trailing ', '.
    sql := sql || ' from ' || qtab;

    raise info 'Execute SQL: %', sql;
    execute sql;
end
$$ language plpgsql;

exemples:

-- This will create a view "avp_person" with "p_" prefix to all column names.
select * from mkaview('public', 'person', 'p_');

select * from avp_person;
4
répondu Xiè Jìléi 2014-10-22 03:48:38

il n'y a pas de norme SQL pour cela.

cependant avec la génération de code (soit à la demande comme les tables sont créées ou modifiées ou à l'exécution), vous pouvez le faire assez facilement:

CREATE TABLE [dbo].[stackoverflow_329931_a](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [col2] [nchar](10) NULL,
    [col3] [nchar](10) NULL,
    [col4] [nchar](10) NULL,
 CONSTRAINT [PK_stackoverflow_329931_a] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[stackoverflow_329931_b](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [col2] [nchar](10) NULL,
    [col3] [nchar](10) NULL,
    [col4] [nchar](10) NULL,
 CONSTRAINT [PK_stackoverflow_329931_b] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

DECLARE @table1_name AS varchar(255)
DECLARE @table1_prefix AS varchar(255)
DECLARE @table2_name AS varchar(255)
DECLARE @table2_prefix AS varchar(255)
DECLARE @join_condition AS varchar(255)
SET @table1_name = 'stackoverflow_329931_a'
SET @table1_prefix = 'a_'
SET @table2_name = 'stackoverflow_329931_b'
SET @table2_prefix = 'b_'
SET @join_condition = 'a.[id] = b.[id]'

DECLARE @CRLF AS varchar(2)
SET @CRLF = CHAR(13) + CHAR(10)

DECLARE @a_columnlist AS varchar(MAX)
DECLARE @b_columnlist AS varchar(MAX)
DECLARE @sql AS varchar(MAX)

SELECT @a_columnlist = COALESCE(@a_columnlist + @CRLF + ',', '') + 'a.[' + COLUMN_NAME + '] AS [' + @table1_prefix + COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table1_name
ORDER BY ORDINAL_POSITION

SELECT @b_columnlist = COALESCE(@b_columnlist + @CRLF + ',', '') + 'b.[' + COLUMN_NAME + '] AS [' + @table2_prefix + COLUMN_NAME + ']'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table2_name
ORDER BY ORDINAL_POSITION

SET @sql = 'SELECT ' + @a_columnlist + '
,' + @b_columnlist + '
FROM [' + @table1_name + '] AS a
INNER JOIN [' + @table2_name + '] AS b
ON (' + @join_condition + ')'

PRINT @sql
-- EXEC (@sql)
2
répondu Cade Roux 2008-12-01 04:58:11

je comprends parfaitement votre problème à propos des noms de champ dupliqués.

j'avais besoin de ça aussi jusqu'à ce que j'ai codé ma propre fonction pour le résoudre. Si vous utilisez PHP, vous pouvez l'utiliser, ou coder la vôtre dans la langue que vous utilisez si vous avez les fonctionnalités suivantes.

le truc ici est que mysql_field_table() renvoie le nom de la table et mysql_field_name() le champ pour chaque ligne dans le résultat s'il est obtenu avec mysql_num_fields() de sorte que vous pouvez les mélanger dans un nouveau tableau.

ce préfixe toutes les colonnes ;)

concerne",

function mysql_rows_with_columns($query) {
    $result = mysql_query($query);
    if (!$result) return false; // mysql_error() could be used outside
    $fields = mysql_num_fields($result);
    $rows = array();
    while ($row = mysql_fetch_row($result)) { 
        $newRow = array();
        for ($i=0; $i<$fields; $i++) {
            $table = mysql_field_table($result, $i);
            $name = mysql_field_name($result, $i);
            $newRow[$table . "." . $name] = $row[$i];
        }
        $rows[] = $newRow;
    }
    mysql_free_result($result);
    return $rows;
}
2
répondu axelbrz 2013-03-22 05:34:42

ou vous pouvez utiliser Red Gate SQL Refactor ou SQL Prompt, qui étend votre SELECT * dans les listes de colonnes avec un clic sur le bouton de L'onglet

donc dans votre cas, si vous tapez SELECT * À partir d'un JOIN B... Aller à la fin de l' *, Onglet bouton, le tour est joué! vous verrez Sélectionnez A. column1, A. column2,.... , B. column1, B. column2 à partir de A 151910920"

Ce n'est pas gratuit, même si les

1
répondu jerryhung 2008-12-02 14:44:50

ne peut pas faire cela sans alias , simplement parce que, comment allez-vous faire référence à un champ dans la clause where, si ce champ existe dans les 2 ou 3 tables que vous rejoignez? Il sera incompréhensible pour mysql lequel vous essayez de référence.

1
répondu kobejr 2011-12-14 05:45:54

j'ai résolu un problème semblable du mien en renommant les champs dans les tables impliquées. Oui, j'ai eu le privilège de faire et de comprendre que tout le monde ne peut pas l'avoir. J'ai ajouté un préfixe à chaque champ dans une table représentant le nom de la table. Ainsi, la LQS affichée par L'OP resterait inchangée -

SELECT a.*, b.* FROM TABLE_A a JOIN TABLE_B b USING (some_id);

et encore donner les résultats attendus - facilité d'identifier à quel tableau les champs de sortie appartiennent.

1
répondu Sam 2017-09-15 14:13:19

il y a deux façons que je peux imaginer pour que cela se produise d'une manière réutilisable. On est à renommer tous vos colonnes avec un préfixe de la table, ils proviennent. J'ai vu de nombreuses fois, mais je n'aime vraiment pas ça. Je trouve que c'est redondant, provoque beaucoup de frappe, et vous pouvez toujours utiliser des alias lorsque vous avez besoin pour couvrir le cas d'un nom de colonne ayant une origine incertaine.

de l'autre côté, ce que je vous recommande de faire dans votre situation si vous êtes engagé à le voir, est de créer des vues pour chaque table d'alias de la table des noms. Alors vous vous joignez contre ces vues, plutôt que les tables. De cette façon, vous êtes libre d'utiliser * si vous le souhaitez, libre d'utiliser les tables d'origine avec les noms de colonnes d'origine si vous le souhaitez, et cela rend également l'écriture de requêtes ultérieures plus facile parce que vous avez déjà fait le travail de renommage dans les vues.

enfin, je ne suis pas clair pourquoi vous devez savoir quel tableau chacune des colonnes est venue de. Est-ce important? Finalement, ce qui compte c'est les données qu'ils contiennent. Que L'identifiant provienne de la table User ou de la table UserQuestion n'a pas vraiment d'importance. Il importe, bien sûr, quand vous avez besoin de le mettre à jour, mais à ce moment-là, vous devriez déjà connaître votre schéma assez bien pour déterminer cela.

0
répondu RedFilter 2008-12-01 04:13:01

si vous êtes préoccupé par les changements de schéma cela pourrait fonctionner pour vous: 1. Lancez une requête' DESCRIBE table ' sur toutes les tables impliquées. 2. Utilisez les noms de champs retournés pour construire dynamiquement une chaîne de noms de colonnes préfixés avec votre alias choisi.

0
répondu Chris Jacob 2009-07-08 06:38:30

il y a une réponse directe à votre question pour ceux qui utilisent L'API C de MySQL.

étant donné le SQL:

  SELECT a.*, b.*, c.* FROM table_a a JOIN table_b b USING (x) JOIN table_c c USING (y)

les résultats de 'mysql_stmt_result_metadata()' donnent la définition de vos champs à partir de votre requête SQL préparée dans la structure MYSQL_FIELD[]. Chaque champ contient les données suivantes:

  char *name;                 /* Name of column (may be the alias) */
  char *org_name;             /* Original column name, if an alias */
  char *table;                /* Table of column if column was a field */
  char *org_table;            /* Org table name, if table was an alias */
  char *db;                   /* Database for table */
  char *catalog;              /* Catalog for table */
  char *def;                  /* Default value (set by mysql_list_fields) */
  unsigned long length;       /* Width of column (create length) */
  unsigned long max_length;   /* Max width for selected set */
  unsigned int name_length;
  unsigned int org_name_length;
  unsigned int table_length;
  unsigned int org_table_length;
  unsigned int db_length;
  unsigned int catalog_length;
  unsigned int def_length;
  unsigned int flags;         /* Div flags */
  unsigned int decimals;      /* Number of decimals in field */
  unsigned int charsetnr;     /* Character set */
  enum enum_field_types type; /* Type of field. See mysql_com.h for types */

notez les champs: catalogue, table, org_name

vous savez maintenant quels champs de votre SQL appartiennent à quel schéma (alias catalogue) et table. Ceci est suffisant pour identifier de façon générique chaque champ à partir d'une requête sql multi-tables, sans avoir à alias quoi que ce soit.

un produit SqlYOG réel est montré à utiliser ces données exactes dans un tel manoir qu'ils sont en mesure de mettre à jour indépendamment chaque table d'une jonction multi-tables, lorsque les champs PK sont présents.

0
répondu J Jorgenson 2010-04-07 22:33:49

en partant de cette solution , voici comment j'aborderais le problème:

d'abord créer une liste de tous les AS énoncés:

DECLARE @asStatements varchar(8000)

SELECT @asStatements = ISNULL(@asStatements + ', ','') + QUOTENAME(table_name) + '.' + QUOTENAME(column_name) + ' AS ' + '[' + table_name + '.' + column_name + ']'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TABLE_A' OR TABLE_NAME = 'TABLE_B'
ORDER BY ORDINAL_POSITION

puis utilisez-le dans votre requête:

EXEC('SELECT ' + @asStatements + ' FROM TABLE_A a JOIN TABLE_B b USING (some_id)');

cependant, cela pourrait nécessiter des modifications car quelque chose de similaire n'est testé que dans SQL Server. Mais ce code ne fonctionne pas exactement dans SQL Server parce que L'utilisation n'est pas supportée.

s'il vous Plaît commentaire si vous le pouvez tester/corriger ce code pour par exemple MySQL.

0
répondu Antonio 2017-05-23 11:33:13

est récemment tombé sur cette question dans NodeJS et Postgres.

approche ES6

il n'y a pas de fonctionnalités RDBMS que je connaisse qui fournissent cette fonctionnalité, donc j'ai créé un objet contenant tous mes champs, par exemple:

const schema = { columns: ['id','another_column','yet_another_column'] }

définit un réducteur pour concaténer les chaînes avec un nom de table:

const prefix = (table, columns) => columns.reduce((previous, column) => {
  previous.push(table + '.' + column + ' AS ' + table + '_' + column);
  return previous;
}, []);

renvoie un tableau de chaînes. L'appeler pour chaque tableau et combiner les résultats:

const columns_joined = [...prefix('tab1',schema.columns), ...prefix('tab2',schema.columns)];

sortie la déclaration finale SQL:

console.log('SELECT ' + columns_joined.join(',') + ' FROM tab1, tab2 WHERE tab1.id = tab2.id');
0
répondu Blair 2018-03-21 11:41:19

select * fait habituellement mauvais code, car les nouvelles colonnes ont tendance à être ajoutées ou l'ordre des colonnes change dans les tables assez fréquemment qui casse habituellement select * de manière très subtile. Donc lister les colonnes est la bonne solution.

quant à la façon de faire votre requête, Pas sûr de mysql mais dans sqlserver vous pouvez sélectionner des noms de colonne à partir de syscolumns et construire dynamiquement la clause select.

-1
répondu Kozyarchuk 2008-12-01 03:24:31

PHP 7.2 + MySQL / Mariadb

MySQL vous enverra plusieurs champs avec le même nom. Même dans le client final. Mais si vous voulez un tableau associatif, vous devrez faire les clés vous-même.

merci à @axelbrz pour l'original. Je l'ai porté sur un nouveau php et je l'ai nettoyé un peu:

function mysqli_rows_with_columns($link, $query) {
    $result = mysqli_query($link, $query);
    if (!$result) {
        return mysqli_error($link);
    }
    $field_count = mysqli_num_fields($result);
    $fields = array();
    for ($i = 0; $i < $field_count; $i++) {
        $field = mysqli_fetch_field_direct($result, $i);
        $fields[] = $field->table . '.' . $field->name; # changed by AS
        #$fields[] = $field->orgtable . '.' . $field->orgname; # actual table/field names
    }
    $rows = array();
    while ($row = mysqli_fetch_row($result)) {
        $new_row = array();
        for ($i = 0; $i < $field_count; $i++) {
            $new_row[$fields[$i]] = $row[$i];
        }
        $rows[] = $new_row;
    }
    mysqli_free_result($result);
    return $rows;
}

$link = mysqli_connect('localhost', 'fixme', 'fixme', 'fixme');
print_r(mysqli_rows_with_columns($link, 'select foo.*, bar.* from foo, bar'));
-1
répondu JasonWoof 2018-06-22 20:41:24