4

我在要加入的不同表中具有相同名称的字段。如ticket.statususer.statustransaction.status。目前查询只返回status.

如何以阻止类似字段名称覆盖的方式获取表名,以便区分字段之间的区别。

简单的说:

$data = array($eventId);
$statement = $this->db->prepare("SELECT * FROM ticket, user, transaction 
                        WHERE ticket.eventId = ? 
                        AND ticket.userId = user.userId
                        AND ticket.transactionId = transaction.transactionId");

$statement->execute($data); 
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);

在我的研究中,我发现PDO::ATTR_FETCH_TABLE_NAMES看起来它可以提供帮助的常量,但我不知道如何实现(我假设通过$statement->setAttribute();某种方式)。

我也担心它不起作用,因为 PHP 文档提到它依赖于驱动程序。

谢谢

4

3 回答 3

3

只需将新别名添加到您的选择语句

$statement = $this->db->prepare("
    SELECT *, ticket.status AS ticket_status, user.status AS user_status, transaction.status AS transaction_status 
    FROM ticket, user, transaction 
    WHERE ticket.eventId = ? 
    AND ticket.userId = user.userId
    AND ticket.transactionId = transaction.transactionId
");

然后你可以做

$rows[0]['user_status'];
$rows[0]['ticket_status'];
$rows[0]['transaction_status'];

如果您真的关心性能,返回的数据量会更大,因此您可以选择每一列而不是添加新别名,然后在status列上放置别名。

于 2013-03-14T16:51:11.213 回答
1

为什么不改变你的实际加入:

SELECT 
t.status as ticket_status, u.status as user_status, tr.status as trans_status
FROM 
ticket as t
inner join user as u on t.userId = u.userId
inner join transaction as tr on t.transactionId = tr.transactionId
where
t.eventId = ?

你甚至不需要使用as something,但我发现它更整洁。

请注意,实际上将解决此问题的列的转换,而不是 join 方法。

于 2013-03-14T16:49:00.403 回答
1

最明显的评论是“不要这样做,这就是存在别名的原因”。但仍有一个很好的潜在问题:MySQL 是否发送有关结果集列来自何处(表、视图或计算)的信息?

显然,确实如此,因为该PDOStatement对象有一个名为getColumnMeta()的实验方法。我一直在测试,它返回一个关联数组,其中table

  • 如果列来自表或视图,则包含源表
  • 如果计算列,则为空字符串

当然,无论如何我都会坚持使用别名。能够使用关联数组对我来说是一个杀手级功能。

于 2013-03-14T17:47:22.987 回答