我想知道这在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);

基本上就是说,“用‘something’为b.*返回的每一列添加前缀”。这可能吗,还是我运气不好?

编辑

关于不使用SELECT *等的建议是有效的建议,但与我的上下文无关,因此请关注眼前的问题——是否可以在连接中为表的所有列名添加前缀(SQL查询中指定的常量)?

我的最终目标是能够通过连接对两个表执行SELECT *操作,并且能够从结果集中获得的列的名称中分辨出哪些列来自表a,哪些列来自表b。同样,我不想单独列出列,我需要能够执行SELECT *操作。


当前回答

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

其他回答

我和OP在同一条船上-我有来自3个不同表的数十个字段,我正在加入,其中一些具有相同的名称(即。身份证、姓名等)。我不想列出每个字段,所以我的解决方案是对共享名称的字段使用别名,并对具有唯一名称的字段使用select *。

例如:

表a: id, 的名字, field1, field2……

表b: id, 的名字, field3, field4……

选择a.id为aID, a.name为ame, a. *, b.id为bID, b.name为bName, b. * .....

当访问结果时,我们这些字段的别名和忽略“原始”名称。

也许不是最好的解决方案,但它为我工作....我用mysql

不同的数据库产品会给你不同的答案;但如果你走得太远,你是在自讨苦吃。您最好选择您想要的列,并为它们提供自己的别名,以便每个列的标识非常清晰,并且可以在结果中区分它们。

Select *通常会导致糟糕的代码,因为往往会添加新列,或者表中列的顺序经常改变,这通常会以非常微妙的方式破坏Select *。所以列出列是正确的解决方案。

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

我可以想到两种方法以可重用的方式实现这一点。一种方法是为所有列重命名,为它们所在的表加上前缀。我已经看过很多次了,但我真的不喜欢。我发现它是多余的,会导致大量的输入,而且当您需要覆盖列名来源不明确的情况时,您总是可以使用别名。

另一种方法是为每个表创建别名表名的视图,这也是我建议您在自己的情况下使用的方法。然后你们就会站在这些观点的对立面,而不是桌子的对立面。这样,如果您愿意,您可以自由地使用*,如果您愿意,可以自由地使用带有原始列名的原始表,而且它还使编写任何后续查询更容易,因为您已经在视图中完成了重命名工作。

最后,我不清楚为什么需要知道每个列来自哪个表。这重要吗?最终重要的是它们所包含的数据。UserID来自User表还是UserQuestion表并不重要。当然,当您需要更新它时,这很重要,但在这一点上,您应该已经足够了解您的模式以确定这一点。

I see two possible situations here. First, you want to know if there is a SQL standard for this, that you can use in general regardless of the database. No, there is not. Second, you want to know with regard to a specific dbms product. Then you need to identify it. But I imagine the most likely answer is that you'll get back something like "a.id, b.id" since that's how you'd need to identify the columns in your SQL expression. And the easiest way to find out what the default is, is just to submit such a query and see what you get back. If you want to specify what prefix comes before the dot, you can use "SELECT * FROM a AS my_alias", for instance.