【问题标题】:JOIN tables but prepend table name to column name to distinguish themJOIN 表,但将表名添加到列名以区分它们
【发布时间】:2020-07-16 19:59:58
【问题描述】:

我想从具有一个或多个连接的表中选择所有列,但我希望能够区分这些列属于哪个表(在列名前加上表名)。我不知道每个表中有哪些列,因此无法手动列出它们。

users:
--------------------------------
| id | name | age | contact_id |
--------------------------------
| 18 | Foo  | 21  | 1          |
| 19 | Bar  | 32  | 2          |

contacts:
----------------------------
| id | address  | phone    |
----------------------------
| 1  | 123 Main | 867-5309 |
| 2  | 987 Wall | 555-5555 |

我想要一些东西:

SELECT * FROM users
JOIN contacts on users.contact_id = contacts.id
WHERE users.id = 18

并得到如下结果:

---------------------------------------------------------------------
| users.id | users.name | ... | contacts.id | contacts.address | ...
---------------------------------------------------------------------
| 18       | Foo        | ... | 1           | 123 Main         | ...

尝试

到目前为止,我发现这是获取每个表的列名:

SELECT concat('contacts.', `COLUMN_NAME`) AS 'contacts'
FROM `INFORMATION_SCHEMA`.`COLUMNS` 
WHERE `TABLE_SCHEMA`='myDb' 
  AND `TABLE_NAME`='contacts'

但我不知道如何将其放回我的选择中,或者这是否是正确的选择。

成功:我对@Bernd Buffen 回答的实现:

我正在使用 PHP 的 PDO 类来获取我的结果,所以我是这样做的。 (我将忽略此示例的 contacts 表,因为它很容易推断。)

$pdo = new PDO(...);
$stmt = $pdo->prepare(<<< EOT
SELECT group_concat(" ", COLUMN_NAME, " AS 'users.", COLUMN_NAME, "'") as 'columns'
    FROM `INFORMATION_SCHEMA`.`COLUMNS`
    WHERE `TABLE_SCHEMA`='myDb'
        AND `TABLE_NAME`='users'
EOT);
$stmt->execute();
$columns = $stmt->fetch()['columns'];

$stmt2 = $pdo->prepare("SELECT $columns FROM users WHERE id = 18 LIMIT 1");
$stmt2->execute();
$result = $stmt2->fetch();

【问题讨论】:

  • 您需要在存储过程中使用动态 SQL 来执行此操作。
  • 查看stackoverflow.com/questions/15507683/… 了解基本示例。
  • @Barmar 诚然我还没有掌握存储过程,但这个例子似乎并没有转化为我想要做的事情。
  • 我没有说它显示了如何做你想做的事情。它展示了使用 INFORMATION_SCHEMA 动态创建查询然后执行该查询的一般原则。
  • 我希望您能从中推断出您的具体用例。

标签: mysql join


【解决方案1】:

这是一个带有预处理语句的示例

看看表格

MariaDB [bernd]> SELECT * FROM users;
+----+------+------+------------+
| id | name | age  | contact_id |
+----+------+------+------------+
| 18 | Foo  |   21 | 1          |
| 19 | Bar  |   32 | 2          |
+----+------+------+------------+
2 rows in set (0.01 sec)

MariaDB [bernd]> SELECT * from contacts;
+----+----------+----------+
| id | address  | phone    |
+----+----------+----------+
|  1 | 123 Main | 867-5309 |
|  2 | 987 Wall | 555-5555 |
+----+----------+----------+
2 rows in set (0.00 sec)

MariaDB [bernd]>

使用 AS 生成字段列表

MariaDB [bernd]> SELECT GROUP_CONCAT(TABLE_NAME,'.',`COLUMN_NAME`," AS '",  
TABLE_NAME,'.', `COLUMN_NAME`,"'" SEPARATOR ', ') 
FROM `INFORMATION_SCHEMA`.`COLUMNS`  
WHERE `TABLE_SCHEMA`='bernd'    
AND `TABLE_NAME` IN ('users','contacts') INTO @allfields;
Query OK, 1 row affected (0.00 sec)

MariaDB [bernd]>

您必须更改 IN 子句中的 TABLE_SCHEMA 和表名

结果存储在@allfields中

现在构建您的查询

MariaDB [bernd]> select CONCAT('SELECT ', @allfields, ' FROM users JOIN contacts on users.contact_id = contacts.id WHERE users.id = 18') into @sql;
Query OK, 1 row affected (0.00 sec)

准备并执行语句

MariaDB [bernd]> PREPARE stmt FROM @sql;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

MariaDB [bernd]> EXECUTE stmt;
+-------------+------------------+----------------+----------+------------+-----------+------------------+
| contacts.id | contacts.address | contacts.phone | users.id | users.name | users.age | users.contact_id |
+-------------+------------------+----------------+----------+------------+-----------+------------------+
|           1 | 123 Main         | 867-5309       |       18 | Foo        |        21 | 1                |
+-------------+------------------+----------------+----------+------------+-----------+------------------+
1 row in set (0.00 sec)

MariaDB [bernd]> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)

MariaDB [bernd]>

【讨论】:

  • 这对我有用!所以本质上,我需要运行 5 条不同的语句才能得到结果?我是准备好的陈述的新手,所以我花了一点时间来了解它在做什么。非常感谢!!
  • 您也可以一步生成孔查询。我只在 2 步中做到了这一点,您可以更好地阅读。并且 PREPARE 可以直接有一个查询。所以您只需要准备、执行和删除 3 个步骤
  • 您是否愿意展示如何一步完成?我想将它作为单个(或几个)PDO 脚本运行。再次感谢您花时间写下所有这些;通过这种细节,我可以掌握更多。
  • 哎呀,电灯开关刚刚翻转。出于某种原因,“准备好的陈述”一词刚刚从我身边走过。基本上从连接的INFORMATION_SCHEMA.COLUMNS 语句中获取字符串,然后将其传递给SELECT @columns FROM my_table。这正是我想要的。我有时有点慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多