SQL select join:是否可以将所有列添加为'prefix。*'?

sql join

115093 观看

21回复

3723 作者的声誉

我想知道这在SQL中是否可行。假设您有两个表A和B,并在表A上执行选择并在表B上进行连接:

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

如果表A包含列'a_id','name'和'some_id',而表B包含'b_id','name'和'some_id',则查询将返回列'a_id','name','some_id ','b_id','name','some_id'。有没有办法为表B的列名添加前缀而不单独列出每一列?相当于:

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

但是,如上所述,没有列出每一列,所以类似于:

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

基本上可以说,“b。*返回的每一列都带有'某事'”。这可能还是我运气不好?

在此先感谢您的帮助!

编辑:不使用SELECT *等建议是有效的建议,但在我的上下文中不相关,所以请坚持手头的问题 - 是否可以添加前缀(SQL查询中指定的常量)给所有连接中表的列名?

编辑:我的最终目标是能够在两个带连接的表上执行SELECT *,并且能够从我在结果集中得到的列的名称中说明哪些列来自表A以及哪些列来自哪些列从表B.再次,我不想单独列出列,我需要能够做一个SELECT *。

作者: foxdonut 的来源 发布者: 2008 年 12 月 1 日

回应 21


5

32897 作者的声誉

不同的数据库产品会给你不同的答案; 但是如果你带着这么远的话,你会让自己受伤。你最好选择你想要的列,并给它们自己的别名,这样每列的标识都是清晰的,你可以在结果中区分它们。

作者: dkretz 发布者: 2008 年 12 月 1 日

-1

9733 作者的声誉

select *通常会导致错误的代码,因为新列往往会被添加或列的顺序在表中频繁更改,这通常会以非常微妙的方式打破select *。列出列是正确的解决方案。

至于如何进行查询,不确定mysql,但在sqlserver中,您可以从syscolumns中选择列名并动态构建select子句。

作者: Kozyarchuk 发布者: 2008 年 12 月 1 日

10

375229 作者的声誉

我知道的唯一数据库是SQLite,具体取决于您配置的设置PRAGMA full_column_namesPRAGMA short_column_names。见http://www.sqlite.org/pragma.html

否则,我建议的是按顺序位置而不是列名来获取结果集中的列,如果在查询中键入列的名称太麻烦了。

这是一个很好的例子,说明为什么使用它是不好的做法SELECT * - 因为最终你需要输入所有的列名。

我理解需要支持可能更改名称或位置的列,但使用通配符会使更难,更容易。

作者: Bill Karwin 发布者: 2008 年 12 月 1 日

34

32897 作者的声誉

决定

我在这看到两种可能的情况。首先,您想知道是否存在针对此的SQL标准,无论数据库如何,您都可以使用该标准。不,那里没有。其次,您想了解特定的dbms产品。然后你需要识别它。但我想最可能的答案是你会得到像“a.id,b.id”这样的东西,因为这就是你需要在SQL表达式中识别列的方法。找出默认设置的最简单方法就是提交这样的查询,看看你得到了什么。如果要在点之前指定前缀,可以使用“SELECT * FROM AS my_alias”。

作者: dkretz 发布者: 2008 年 12 月 1 日

0

134541 作者的声誉

我可以通过两种方式来考虑以可重用的方式实现这一点。一种是使用它们来自的表的前缀重命名所有列。我见过很多次,但我真的不喜欢它。我发现这是多余的,导致大量的输入,并且当您需要覆盖具有不明原点的列名称的情况时,您总是可以使用别名。

另一种方式,如果你致力于通过这种方式,我建议你在你的情况下做的是为每个表创建视图,这些表是别名表名。然后你加入反对那些观点,而不是表格。这样,如果您愿意,您可以自由使用*,如果您愿意,可以随意使用带有原始列名的原始表,并且还可以更轻松地编写任何后续查询,因为您已经在视图中完成了重命名工作。

最后,我不清楚为什么你需要知道每个列来自哪个表。这有关系吗?最重要的是它们包含的数据。UserID来自User表还是UserQuestion表并不重要。当然,当您需要更新它时,这很重要,但此时您应该已经足够了解您的架构以确定它。

作者: RedFilter 发布者: 2008 年 12 月 1 日

2

72935 作者的声誉

这没有SQL标准。

但是,通过代码生成(在创建或更改表时或在运行时根据需要),您可以非常轻松地执行此操作:

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)
作者: Cade Roux 发布者: 2008 年 12 月 1 日

5

0 作者的声誉

我与OP的船相同 - 我有3个不同的表中的几十个字段,我正在加入,其中一些具有相同的名称(即id,名称等)。我不想列出每个字段,因此我的解决方案是为共享名称的字段添加别名,并对具有唯一名称的字段使用select *。

例如 :

表a:id,name,field1,field2 ......

表b:id,name,field3,field4 ......

选择a.id作为aID,a.name作为aName,a。*,b.id为bID,b.name为bName,b。* .....

访问结果时,我使用这些字段的别名,并忽略“原始”名称。

也许不是最好的解决方案,但它适用于我....我使用的是mysql

作者: bdt 发布者: 2008 年 12 月 2 日

1

865 作者的声誉

或者您可以使用Red Gate SQL Refactor或SQL Prompt,只需单击Tab按钮即可将SELECT *扩展为列列表

所以在你的情况下,如果你输入SELECT * FROM A JOIN B ...转到*,Tab键的结尾,瞧!你会看到SELECT A.column1,A.column2,....,B.column1,B.column2 FROM A JOIN B

但它不是免费的

作者: jerryhung 发布者: 2008 年 12 月 2 日

0

7260 作者的声誉

如果担心架构更改,这可能对您有用:1。对所涉及的所有表运行“DESCRIBE表”查询。2.使用返回的字段名称动态构造一个以您选择的别名为前缀的列名字符串。

作者: Chris Jacob 发布者: 2009 年 7 月 8 日

0

1090 作者的声誉

对于那些使用MySQL C-API的人,您可以直接回答您的问题。

鉴于SQL:

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

'mysql_stmt_result_metadata()'的结果给出了从准备好的SQL查询到结构MYSQL_FIELD []的字段定义。每个字段包含以下数据:

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

请注意字段:catalog,table,org_name

您现在知道SQL中的哪些字段属于哪个模式(即目录)和表。这足以从多表sql查询中一般地标识每个字段,而不必别名。

显示实际产品SqlYOG以在这样的庄园中使用该确切数据,使得当PK字段存在时,它们能够独立地更新多表连接的每个表。

作者: J Jorgenson 发布者: 2010 年 4 月 7 日

1

11 作者的声誉

如果没有别名,就不能这样做,只是因为,如果您要加入的2或3个表中存在该字段,您将如何引用where子句中的字段?对于mysql,您将尝试引用哪一个,这一点尚不清楚。

作者: kobejr 发布者: 2011 年 12 月 14 日

19

3015 作者的声誉

我完全理解为什么这是必要的 - 至少对我而言,在快速原型制作过程中,当需要加入很多表时,包括许多内部连接时,它很方便。只要第二个“joinedtable。*”字段通配符中的列名相同,主表的字段值将使用jointable值覆盖。当必须手动指定带有别名的表字段时,容易出错,令人沮丧并且违反DRY ......

这是一个PHP(Wordpress)函数,通过代码生成以及如何使用它的示例实现此目的。在该示例中,它用于快速生成自定义查询,该查询将提供通过高级自定义字段字段引用的相关wordpress帖子的字段。

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

输出:

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
        )
)
作者: Motin 发布者: 2012 年 1 月 19 日

56

561 作者的声誉

似乎你的问题的答案是否定的,但是你可以使用的一个黑客是分配一个虚拟列来分隔每个新表。如果您在脚本语言(如Python或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

我意识到这并不能完全回答你的问题,但如果你是一个编码器,这是一个很好的方法来分隔具有重复列名的表。希望这有助于某人。

作者: Wayne Bryan 发布者: 2012 年 3 月 29 日

2

547 作者的声誉

我完全理解你关于重复字段名称的问题。

我也需要它,直到我编写自己的函数来解决它。如果您使用的是PHP,则可以使用它,或者如果您有以下设施,则使用您所使用的语言编写代码。

这里的技巧是mysql_field_table()返回mysql_field_name()结果中每一行的表名和字段,如果它已经存在,mysql_num_fields()那么你可以将它们混合在一个新的数组中。

这是所有列的前缀;)

问候,

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;
}
作者: axelbrz 发布者: 2013 年 3 月 22 日

4

6279 作者的声誉

这个问题在实践中非常有用。只需要列出软件编程中的每个显式列,您需要特别注意处理所有条件。

想象一下,在调试时,或者尝试使用DBMS作为日常办公工具,而不是特定程序员的抽象底层基础架构的可变实现,我们需要编写大量的SQL代码。该场景随处可见,如数据库转换,迁移,管理等。这些SQL中的大多数只执行一次,永远不会再次使用,给每个列名称只是浪费时间。并且不要忘记SQL的发明不仅仅是程序员使用的。

通常我会创建一个以列名称为前缀的实用程序视图,这里是pl / pgsql中的函数,这并不容易,但您可以将其转换为其他过程语言。

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

例子:

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

select * from avp_person;
作者: Xiè Jìléi 发布者: 2014 年 10 月 22 日

0

11624 作者的声誉

这个解决方案开发,我就是这样解决问题的方法:

首先创建所有AS语句的列表:

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

然后在您的查询中使用它:

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

但是,这可能需要修改,因为类似的东西仅在SQL Server中测试。但是这段代码在SQL Server中并不完全有效,因为不支持USING。

如果您可以测试/更正此代码,请评论,例如MySQL。

作者: Antonio 发布者: 2015 年 9 月 9 日

1

11 作者的声誉

我通过重命名所涉及的表中的字段解决了我的类似问题。是的,我有幸做到这一点并明白每个人都可能没有。我在表中表示表名的每个字段中添加了前缀。因此OP发布的SQL将保持不变 -

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

并且仍然给出预期的结果 - 易于识别输出字段属于哪个表。

作者: Sam 发布者: 2017 年 9 月 15 日

0

2351 作者的声誉

最近在NodeJS和Postgres中遇到了这个问题。

ES6方法

我知道没有任何提供此功能的RDBMS功能,因此我创建了一个包含所有字段的对象,例如:

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

定义了一个reducer,用于将字符串与表名连接在一起:

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

这将返回一个字符串数组。为每个表调用它并合并结果:

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

输出最终的SQL语句:

console.log('SELECT ' + columns_joined.join(',') + ' FROM tab1, tab2 WHERE tab1.id = tab2.id');
作者: Blair 发布者: 2018 年 3 月 21 日

-1

3398 作者的声誉

PHP 7.2 + MySQL / Mariadb

MySQL会向您发送多个具有相同名称的字段。即使在终端客户端。但是如果你想要一个关联数组,你必须自己制作密钥。

感谢@axelbrz的原创。我把它移植到更新的php并清理了一下:

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'));
作者: JasonWoof 发布者: 2018 年 6 月 22 日

0

7196 作者的声誉

我根据建议在节点中使用dummy或sentinel列的答案实现了一个解决方案。您可以通过生成SQL来使用它:

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

然后对从数据库驱动程序返回的行进行后期处理addPrefixes(row)

实现(基于我的驱动程序返回fields/ rows,但其他数据库驱动程序应该很容易更改):

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
}

测试:

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)
  })
})
作者: Carl G 发布者: 2018 年 11 月 1 日

0

1 作者的声誉

我所做的是使用Excel来连接过程。例如,首先我选择*并获取所有列,将它们粘贴到Excel中。然后写出我需要围绕列的代码。说我需要广告上一堆专栏。我的字段位于一列中,而“B中的字段为”,而字段c中的字段为“prev_”。在d栏中,我有一个专栏。

然后在列e中使用concatanate并将它们合并在一起,确保包含空格。然后将其剪切并粘贴到您的sql代码中。我还使用此方法为多个字段表中的每个字段创建相同字段和其他更长代码的case语句。

作者: Nathan Michael 发布者: 2019 年 1 月 29 日
32x32