SQL select join: ¿es posible prefijar todas las columnas como 'prefijo. *'?

Me pregunto si esto es posible en SQL. Digamos que tiene dos mesas A y B, y hace una selección en la mesa A y se une a la mesa B:

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

Si la tabla A tiene las columnas 'a_id', 'name' y 'some_id', y la tabla B tiene 'b_id', 'name' y 'some_id', la consulta devolverá las columnas 'a_id', 'name', 'some_id ',' b_id ',' nombre ',' algún_id '. ¿Hay alguna forma de prefijar los nombres de las columnas de la tabla B sin enumerar cada columna individualmente? El equivalente de esto:

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);

Pero, como se mencionó, sin enumerar todas las columnas, algo como:

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

Básicamente algo que decir, "prefija cada columna devuelta por b. * Con 'algo'". ¿Es esto posible o no tengo suerte?

EDICIONES

Consejos sobre no usar SELECT * y así sucesivamente es un consejo válido pero no relevante en mi contexto, así que por favor, céntrese en el problema en cuestión: ¿es posible agregar un prefijo (una constante especificada en la consulta SQL) a todos los nombres de columna de una tabla en una combinación? ?

Mi objetivo final es poder hacer un SELECT * en dos tablas con una combinación, y poder decir, a partir de los nombres de las columnas que obtengo en mi conjunto de resultados, qué columnas provienen de la tabla A y qué columnas provienen de la tabla B. Nuevamente, no quiero tener que hacerlo enumerar columnas individualmente, necesito poder hacer una SELECT *.

preguntado el 01 de diciembre de 08 a las 01:12

¿Cuál espera exactamente que sea el resultado de su consulta? Estoy confundido -

GregD: Quiero que todos los nombres de columna que salen de b. * Tengan como prefijo alguna constante que yo especifique. Por ejemplo, en lugar de 'nombre' y 'número', quiero especificar, digamos, el prefijo 'especial_' y obtener 'nombre_especial' y 'número_especial'. Pero no quiero hacer esto para cada columna individualmente. -

Cuando hago una SELECCIÓN rápida para ver columnas de varias tablas, en algún momento selecciono 'AAAAA', A. *, 'BBBBB', B. * FROM TableA AS A JOIN TableB AS B ON A.ID = B.ID para que yo al menos tener un identificador de tabla al escanear a lo largo de las filas -

22 Respuestas

Veo dos situaciones posibles aquí. Primero, desea saber si existe un estándar SQL para esto, que pueda usar en general independientemente de la base de datos. No no hay. En segundo lugar, desea saber con respecto a un producto dbms específico. Entonces necesitas identificarlo. Pero imagino que la respuesta más probable es que obtendrá algo como "a.id, b.id", ya que así es como necesitaría identificar las columnas en su expresión SQL. Y la forma más fácil de averiguar cuál es el valor predeterminado es enviar una consulta de este tipo y ver lo que obtiene. Si desea especificar qué prefijo viene antes del punto, puede usar "SELECT * FROM a AS my_alias", por ejemplo.

Respondido el 22 de diciembre de 11 a las 17:12

No estoy seguro de cómo esto responde a su pregunta. Estoy usando MS SQL Server y agrego un alias después de que el nombre de la tabla no agrega el alias a los nombres de las columnas en el conjunto de resultados. - paiego

Parece que la respuesta a su pregunta es no, sin embargo, un truco que puede utilizar es asignar una columna ficticia para separar cada nueva tabla. Esto funciona especialmente bien si está recorriendo un conjunto de resultados para una lista de columnas en un lenguaje de programación como Python o 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

Me doy cuenta de que esto no responde exactamente a su pregunta, pero si es un codificador, esta es una excelente manera de separar tablas con nombres de columna duplicados. Espero que esto ayude a alguien.

Respondido 07 ago 12, 15:08

Me ayuda. Muchas gracias por compartir - Chidiebere

Entiendo totalmente por qué esto es necesario, al menos para mí es útil durante la creación rápida de prototipos cuando es necesario unir muchas tablas, incluidas muchas combinaciones internas. Tan pronto como el nombre de una columna es el mismo en un segundo comodín de campo "jointable. *", Los valores de campo de la tabla principal se reemplazan con los valores de la tabla unida. Propenso a errores, frustrante y una violación de DRY al tener que especificar manualmente los campos de la tabla con alias una y otra vez ...

Aquí hay una función PHP (Wordpress) para lograr esto a través de la generación de código junto con un ejemplo de cómo usarlo. En el ejemplo, se utiliza para generar rápidamente una consulta personalizada que proporcionará los campos de una publicación de wordpress relacionada a la que se hizo referencia a través de una campos personalizados avanzados campo.

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 salida:

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
        )
)

Respondido el 19 de enero de 12 a las 16:01

esta publicación es un poco antigua, pero el enfoque de funciones es definitivamente elegante y funciona bien. - glihm

La única base de datos que conozco que hace esto es SQLite, dependiendo de la configuración que configure con PRAGMA full_column_names y PRAGMA short_column_names. Ver http://www.sqlite.org/pragma.html

De lo contrario, todo lo que puedo recomendar es buscar columnas en un conjunto de resultados por posición ordinal en lugar de por nombre de columna, si es demasiado problema para usted escribir los nombres de las columnas en su consulta.

Este es un buen ejemplo de por qué es una mala práctica usar SELECT * - porque eventualmente tendrás que escribir todos los nombres de las columnas de todos modos.

Entiendo la necesidad de admitir columnas que pueden cambiar de nombre o posición, pero el uso de comodines hace que más fuerte, no más fácil.

contestado el 23 de mayo de 17 a las 13:05

Tenga en cuenta que ambos full_column_names y short_column_names se encuentran las en SQLite. - isanae

Estoy en el mismo barco que OP: tengo docenas de campos de 3 tablas diferentes a las que me estoy uniendo, algunas de las cuales tienen el mismo nombre (es decir, id, nombre, etc.). No quiero enumerar cada campo, por lo que mi solución fue poner un alias en los campos que compartían un nombre y usar select * para aquellos que tienen un nombre único.

Por ejemplo:

tabla a: id, nombre, campo1, campo2 ...

tabla b: id, nombre, campo3, campo4 ...

seleccione a.id como aID, a.name como aName, a. *, b.id como bID, b.name como bName, b. * .....

Al acceder a los resultados, utilizo los nombres con alias para estos campos e ignoro los nombres "originales".

Tal vez no sea la mejor solución, pero funciona para mí ... estoy usando mysql

Respondido el 02 de diciembre de 08 a las 14:12

Esta pregunta es muy útil en la práctica. Solo es necesario enumerar todas las columnas explícitas en la programación de software, donde preste especial atención para lidiar con todas las condiciones.

Imagínese al depurar, o intentar utilizar DBMS como herramienta de oficina diaria, en lugar de una implementación alterable de la infraestructura subyacente abstracta de un programador específico, necesitamos codificar una gran cantidad de SQL. El escenario se puede encontrar en todas partes, como conversión de base de datos, migración, administración, etc. La mayoría de estos SQL se ejecutarán solo una vez y nunca se volverán a usar, dar los nombres de cada columna es solo una pérdida de tiempo. Y no olvide que la invención de SQL no es solo para uso de los programadores.

Por lo general, crearé una vista de utilidad con nombres de columna prefijados, aquí está la función en pl / pgsql, no es fácil, pero puede convertirla a otros lenguajes de procedimientos.

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

Ejemplos:

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

select * from avp_person;

Respondido 22 Oct 14, 04:10

Diferentes productos de bases de datos le darán diferentes respuestas; pero te estás poniendo en peligro si llegas tan lejos. Es mucho mejor que elija las columnas que desee y les dé sus propios alias para que la identidad de cada columna sea clara y pueda diferenciarlas en los resultados.

Respondido el 01 de diciembre de 08 a las 03:12

Punto tomado, pero mi objetivo aquí es algo muy genérico, por lo que no ser explícito no es un problema. De hecho, tener que ser específico se ser un problema. - rosquilla

Consulte la presentación adicional a continuación. ¿Puede usar dot.notation, que es probablemente lo que obtendrá por defecto? - dkretz

Es importante para la legibilidad. Tenía la esperanza de hacer esto ahora mismo porque tengo un proceso de CTE similar. ex. CTE_A -> CTE_B -> CTE_C -> CTE_D -> seleccionar / insertar No es necesario especificar las columnas que quiero hasta que la declaración de selección final y el rendimiento no sean una consideración. - ThomasRones

Entiendo totalmente su problema con los nombres de campo duplicados.

También lo necesitaba hasta que codifiqué mi propia función para resolverlo. Si está usando PHP, puede usarlo, o codificar el suyo en el idioma que está usando si tiene las siguientes funciones.

El truco aquí es que mysql_field_table() devuelve el nombre de la tabla y mysql_field_name() el campo para cada fila en el resultado si tiene mysql_num_fields() para que pueda mezclarlos en una nueva matriz.

Esto antepone todas las columnas;)

Saludos,

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;
}

respondido 22 mar '13, 05:03

No existe un estándar SQL para esto.

Sin embargo, con la generación de código (ya sea a pedido a medida que se crean o modifican las tablas o en tiempo de ejecución), puede hacer esto con bastante facilidad:

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)

Respondido el 01 de diciembre de 08 a las 04:12

esto funcionaría, pero la pregunta es bastante tonta. ¿Por qué no simplemente realizar una unión o subconsulta? ¿Por qué se uniría y seguiría queriendo prefijos de tabla en los nombres de las columnas? - D3vtr0n

Cade: gracias por la información, eso es interesante. Desafortunadamente, generar / alterar la base de datos no es una opción en mi caso. Devtron: si está tratando de mapear la información que proviene de una consulta a diferentes propiedades de un objeto, esa información se vuelve muy útil. - rosquilla

A veces, los nombres de las columnas en diferentes tablas son iguales, pero no contienen los mismos valores. De ahí la necesidad de prefijarlos para distinguirlos en vistas o tablas derivadas (que deben tener todos los nombres de columna únicos). - cade roux

@Frederic, tu código tiene que vivir en algún lugar, esto solo genera el código. Nuevamente, esto se puede hacer una vez durante el desarrollo o dinámicamente en tiempo de ejecución. - cade roux

Resolví un problema similar al cambiar el nombre de los campos en las tablas involucradas. Sí, tuve el privilegio de hacer esto y entiendo que es posible que no todos lo tengan. Agregué un prefijo a cada campo dentro de una tabla que representa el nombre de la tabla. Por lo tanto, el SQL publicado por OP se mantendría sin cambios:

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

y aún así dar los resultados esperados: facilidad para identificar a qué tabla pertenecen los campos de salida.

Respondido el 15 de Septiembre de 17 a las 15:09

Hay dos formas en las que puedo pensar para hacer que esto suceda de una manera reutilizable. Una es cambiar el nombre de todas sus columnas con un prefijo para la tabla de la que provienen. Lo he visto muchas veces, pero realmente no me gusta. Encuentro que es redundante, causa mucho tipeo y siempre puede usar alias cuando necesita cubrir el caso de un nombre de columna que tiene un origen poco claro.

La otra forma, que le recomendaría hacer en su situación si está comprometido a llevar esto a cabo, es crear vistas para cada tabla que tengan un alias en los nombres de las tablas. Luego te unes a esos puntos de vista, en lugar de a las tablas. De esa manera, puede usar * si lo desea, puede usar las tablas originales con los nombres de las columnas originales si lo desea, y también facilita la escritura de consultas posteriores porque ya ha realizado el trabajo de cambio de nombre en las vistas.

Finalmente, no tengo claro por qué necesita saber de qué tabla proviene cada una de las columnas. ¿Importa esto? En definitiva, lo que importa son los datos que contienen. No importa si UserID proviene de la tabla User o de la tabla UserQuestion. Es importante, por supuesto, cuándo necesita actualizarlo, pero en ese momento ya debería conocer su esquema lo suficientemente bien como para determinarlo.

Respondido el 01 de diciembre de 08 a las 04:12

"Finalmente, no tengo claro por qué necesita saber de qué tabla proviene cada una de las columnas. ¿Importa esto?" <- 11 años después, un caso de uso es el escaneo de estructuras en Go. - lee benson

O puede usar Red Gate SQL Refactor o SQL Prompt, que expande su SELECT * en listas de columnas con un clic del botón Tab

así que en su caso, si escribe SELECT * FROM A JOIN B ... Vaya al final de *, botón Tab, ¡voilá! verá SELECT A.column1, A.column2, ...., B.column1, B.column2 FROM A JOIN B

Aunque no es gratis

Respondido el 02 de diciembre de 08 a las 14:12

No puedo hacer esto sin alias, simplemente porque, ¿cómo va a hacer referencia a un campo en la cláusula where, si ese campo existe en las 2 o 3 tablas a las que se une? No estará claro para mysql a cuál está intentando hacer referencia.

Respondido el 14 de diciembre de 11 a las 05:12

Recientemente encontré este problema en NodeJS y Postgres.

Enfoque ES6

No conozco ninguna característica de RDBMS que proporcione esta funcionalidad, así que creé un objeto que contiene todos mis campos, por ejemplo:

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

Definió un reductor para concatenar las cadenas junto con un nombre de tabla:

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

Esto devuelve una matriz de cadenas. Llámelo para cada tabla y combine los resultados:

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

Genere la declaración SQL final:

console.log('SELECT ' + columns_joined.join(',') + ' FROM tab1, tab2 WHERE tab1.id = tab2.id');

respondido 21 mar '18, 11:03

¡De ninguna manera! Esa es una inyección SQL hacky y no funciona con expresiones. - ratijas

En postgres, utilizo las funciones json para devolver objetos json ... luego, después de consultar, json_decode los campos con un sufijo _json.

IE:

select row_to_json(tab1.*),tab1_json, row_to_json(tab2.*) tab2_json 
 from tab1
 join tab2 on tab2.t1id=tab1.id

luego, en PHP (o cualquier otro idioma), recorro las columnas devueltas y json_decode () si tienen el sufijo "_json" (también elimino el sufijo. Al final, obtengo un objeto llamado "tab1" que incluye todo campos tab1, y otro llamado "tab2" que incluye todos los campos tab2.

Respondido el 20 de enero de 20 a las 18:01

select * generalmente genera un código incorrecto, ya que tienden a agregarse nuevas columnas o el orden de las columnas cambia en las tablas con bastante frecuencia, lo que generalmente rompe select * de una manera muy sutil. Entonces, enumerar las columnas es la solución correcta.

En cuanto a cómo hacer su consulta, no estoy seguro acerca de mysql pero en sqlserver puede seleccionar nombres de columnas de syscolumns y construir dinámicamente la cláusula select.

Respondido el 01 de diciembre de 08 a las 03:12

Punto tomado, pero en mi contexto, necesito algo genérico y dinámico, por lo que, de hecho, mi código se adaptará a las nuevas columnas que se agregan / reordenan / etc. No quiero tener que enumerar las columnas individualmente. - rosquilla

Seleccionar de syscolumns para construir dinámicamente una declaración de selección es un truco terrible, y no lo recomendaría en producción. - Julieta

Si le preocupan los cambios de esquema, esto podría funcionar para usted: 1. Ejecute una consulta 'DESCRIBE tabla' en todas las tablas involucradas. 2. Utilice los nombres de campo devueltos para construir dinámicamente una cadena de nombres de columna con el prefijo de su alias elegido.

Respondido 08 Jul 09, 07:07

Hay una respuesta directa a su pregunta para aquellos que usan MySQL C-API.

Dado el SQL:

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

Los resultados de 'mysql_stmt_result_metadata ()' dan la definición de sus campos de su consulta SQL preparada en la estructura MYSQL_FIELD []. Cada campo contiene los siguientes datos:

  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 */

Fíjate en los campos: catálogo, tabla, org_name

Ahora sabe qué campos de su SQL pertenecen a qué esquema (también conocido como catálogo) y tabla. Esto es suficiente para identificar genéricamente cada campo de una consulta sql de varias tablas, sin tener que asignar un alias a nada.

Se muestra un producto real SqlYOG para usar estos datos exactos de tal manera que puedan actualizar de forma independiente cada tabla de una combinación de múltiples tablas, cuando los campos PK están presentes.

Respondido 07 Abr '10, 23:04

Desarrollando a partir de esta solución, así es como abordaría el problema:

Primero cree una lista de todos los AS declaraciones:

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

Luego utilícelo en su consulta:

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

Sin embargo, esto podría necesitar modificaciones porque algo similar solo se prueba en SQL Server. Pero este código no funciona exactamente en SQL Server porque USING no es compatible.

Por favor comente si puede probar / corregir este código para, por ejemplo, MySQL.

contestado el 23 de mayo de 17 a las 12:05

PHP 7.2 + MySQL / Mariadb

MySQL le enviará varios campos con el mismo nombre. Incluso en el cliente terminal. Pero si desea una matriz asociativa, tendrá que hacer las claves usted mismo.

Gracias a @axelbrz por el original. Lo porté a un php más nuevo y lo limpié un poco:

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'));

Respondido el 22 de junio de 18 a las 21:06

Implementé una solución basada en la respuesta sugiere el uso de columnas ficticias o centinela en nodo. Lo usaría generando SQL como:

select 
    s.*
  , '' as _prefix__creator_
  , u.*
  , '' as _prefix__speaker_
  , p.*
from statements s 
  left join users u on s.creator_user_id = u.user_id
  left join persons p on s.speaker_person_id = p.person_id

Y luego posprocesar la fila que obtiene de su controlador de base de datos como addPrefixes(row).

Implementación (basada en la fields/rows devuelto por mi controlador, pero debería ser fácil de cambiar para otros controladores de base de datos):

const PREFIX_INDICATOR = '_prefix__'
const STOP_PREFIX_INDICATOR = '_stop_prefix'

/** Adds a <prefix> to all properties that follow a property with the name: PREFIX_INDICATOR<prefix> */
function addPrefixes(fields, row) {
  let prefix = null
  for (const field of fields) {
    const key = field.name
    if (key.startsWith(PREFIX_INDICATOR)) {
      if (row[key] !== '') {
        throw new Error(`PREFIX_INDICATOR ${PREFIX_INDICATOR} must not appear with a value, but had value: ${row[key]}`)
      }
      prefix = key.substr(PREFIX_INDICATOR.length)
      delete row[key]
    } else if (key === STOP_PREFIX_INDICATOR) {
      if (row[key] !== '') {
        throw new Error(`STOP_PREFIX_INDICATOR ${STOP_PREFIX_INDICATOR} must not appear with a value, but had value: ${row[key]}`)
      }
      prefix = null
      delete row[key]
    } else if (prefix) {
      const prefixedKey = prefix + key
      row[prefixedKey] = row[key]
      delete row[key]
    }
  }
  return row
}

Prueba:

const {
  addPrefixes,
  PREFIX_INDICATOR,
  STOP_PREFIX_INDICATOR,
} = require('./BaseDao')

describe('addPrefixes', () => {
  test('adds prefixes', () => {
    const fields = [
      {name: 'id'},
      {name: PREFIX_INDICATOR + 'my_prefix_'},
      {name: 'foo'},
      {name: STOP_PREFIX_INDICATOR},
      {name: 'baz'},
    ]
    const row = {
      id: 1,
      [PREFIX_INDICATOR + 'my_prefix_']: '',
      foo: 'bar',
      [STOP_PREFIX_INDICATOR]: '',
      baz: 'spaz'
    }
    const expected = {
      id: 1,
      my_prefix_foo: 'bar',
      baz: 'spaz',
    }
    expect(addPrefixes(fields, row)).toEqual(expected)
  })
})

respondido 01 nov., 18:21

Lo que hago es usar Excel para concatenar el procedimiento. Por ejemplo, primero selecciono * y obtengo todas las columnas, las pego en Excel. Luego escriba el código que necesito para rodear la columna. Digamos que necesitaba agregar un anuncio anterior a un montón de columnas. Tendría mis campos en la columna a y "as prev_" en la columna B y mis campos nuevamente en la columna c. En la columna d tendría una columna.

Luego use concatanate en la columna e y combínelos, asegurándose de incluir espacios. Luego corte y pegue esto en su código sql. También he usado este método para hacer declaraciones de casos para el mismo campo y otros códigos más largos que necesito hacer para cada campo en una tabla de campos de varios cientos.

Respondido el 29 de enero de 19 a las 13:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.