【问题标题】:Selecting multiple values from two table at once一次从两个表中选择多个值
【发布时间】:2012-03-05 08:40:43
【问题描述】:

代码

目前我的代码是这样的。

            $stmt = $this->db->prepare("SELECT m.id, m.from_id, m.to_id, m.subject, m.date, m.deleted, m.read, u.fname, u.mname, u.lname FROM msghistory AS m,users AS u WHERE m.from_id=u.id AND m.to_id=u.id AND GROUP BY m.id DESC");
            $stmt->execute();
            $stmt->store_result();
            if ($stmt->affected_rows > 0) {
                $msg = array();
                $stmt->bind_result($msg['id'], $msg['from_name'], $msg['to_name'], $msg['subject'], $msg['message'], $msg['date'], $msg['deleted'], $msg['read']);

                while ($stmt->fetch()) {
                    <echoing results one by one>                    }
            }

我想做什么

我想将u.fname+u.mname+u.lnamemsghistory.from_id=users.id)作为$msg['from_name'],再次将u.fname+u.mname+u.lname但是这次msghistory.to_id=users.id)作为$msg['to_name']。

示例

message | from_id | to-id
hi      | 1       | 5

如您所见,这意味着用户 1 向用户 5 发送消息 hi。

假设在用户表 fname 中,用户 id=1 的 lname - John Doe 和 5 - George Smith 我想将其显示为输出结果

message | from_id | to-id
hi      | John Doe| George Smith

问题

我知道至少有 3 个查询是可能的。但试图找到最佳方式。那么,这可以通过一个且唯一的查询来实现吗?

更新

根据用户的 2 个有用的答案,我将查询修改为此

            $stmt = $this->db->prepare("SELECT 
                message.id, message.from_id, message.to_id, message.subject, 
                message.date, message.deleted, message.read, 
                CONCAT_WS(' ',sender.fname, sender.mname, sender.lname) AS sender_name, 
                CONCAT_WS(' ',recipient.fname, recipient.mname, recipient.lname) AS recipient_name,  
                FROM msghistory AS message 
                LEFT JOIN users AS sender ON sender.id=message.from_id, 
                LEFT JOIN users AS recipient ON recipient.id=message.to_id 
                GROUP BY message.id DESC");

【问题讨论】:

    标签: php mysql email mysqli prepared-statement


    【解决方案1】:
    SELECT m.id, m.from_id, m.to_id, m.subject, m.date, 
    m.deleted, m.read, u1.fname, u1.mname, u1.lname, 
    u2.fname, u2.mname, u2.lname,       
    FROM msghistory AS m,users AS u1, users As u2     
    WHERE m.from_id=u1.id AND m.to_id=u2.id 
    GROUP BY m.id DESC
    

    我不确定您是否需要“分组依据”

    【讨论】:

    • 按 for 分组,降序排序。顺便说一句,我可以选择 u1.fname、u1.mname、u1.lname 作为 1 个变量 name1(换句话说,将它们与查询内的空格内爆成 1 个变量 name1)?
    • CONCAT(u1.fname, " ", u1.lname) AS 'name'
    • 我认为如果其中一些值为空,concat 将不起作用。所以 concat_ws 很适合这个目的,对吧?
    • concat_ws 将添加逗号 - 不确定这是否是您想要的行为。如果有机会获得 NULL 值 - 我会使用 NVL(u1.fname,'N/A')
    • 几乎完美:concat_ws 将返回以逗号分隔的字符串,因为您以空格开头,输出看起来像“,first name,lastname...” - 您可能不想要第一个逗号。
    【解决方案2】:

    使用显式连接和清晰易读的别名使其成为更健壮的查询并且更易于阅读。请尝试以下操作:

    SELECT message.*, recipient.*, sender.*
    FROM msghistory AS message
    INNER JOIN users AS recipient ON recipient.id=m.to_id
    INNER JOIN users AS sender ON sender.id=m.from_id
    

    您可以将 select *s 替换为您想要提高效率的字段

    【讨论】:

    • 看起来不错。如果发送方和接收方是可选的,则只需要左连接(而不是内连接)。如果消息总是有发送者和接收者,那么使用内部连接,因为它们更有效。我不知道您可以使用 group by 子句指定 asc 或 desc 方向。好知识!
    猜你喜欢
    • 2014-05-04
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多