将包含 JOIN、GROUP BY 以及带有 INTERVAL 的 UNIX_TIMESTAMP 和 NOW() 函数调用的 MySQL 查询转换为 CodeIgniter 活动记录脚本

问题描述 投票:0回答:2

如何将以下内容转换为正确的 codeigniter 活动记录语法。

function postsInterest($user_id)
{
    $query = $this->db->query("
    SELECT b.*,
           users.country,
           users.company,
           users.pic_small,
           users.subscription,
           COUNT(leads.user_id) AS leads
    FROM trading AS u
    INNER JOIN trading AS b
    LEFT JOIN users ON users.user_id = b.user_id
    LEFT JOIN leads ON b.trade_id = leads.trade_id
    WHERE u.stock_type = b.stock_type
        AND u.buying_selling != b.buying_selling
        AND u.bond = b.bond
        AND u.user_id = $user_id
        AND b.user_id != $user_id
        AND u.timestamp > unix_timestamp(now() - interval 120 DAY)
        AND b.timestamp > unix_timestamp(now() - interval 120 DAY)
    GROUP BY b.trade_id
    ORDER BY b.timestamp DESC");
    if ($query->num_rows() > 0) {
        return $query->result_array();
    } else {
        return false;
    }
}

以上内容可用于快速修复,但希望使其与其余查询保持一致,以便我可以使用分页库。

php mysql activerecord codeigniter-3 query-builder
2个回答
1
投票

我不确定该查询是否有效。

INNER JOIN trading AS b
但是没有指定连接条件,尽管所需的谓词位于where子句中。这些是“加入条件”

WHERE u.stock_type = b.stock_type
    AND u.buying_selling != b.buying_selling
    AND u.bond = b.bond

其中每一个的一侧都有一张桌子

u
,另一侧也有一张桌子
b
。当使用显式连接语法时,您应该将所有此类谓词移动到连接上。

我相信你会更成功地将其转换为 codeigniter 语法:

SELECT
      b.*
    , users.country
    , users.company
    , users.pic_small
    , users.subscription
    , COUNT(leads.user_id) AS leads
FROM trading AS u
INNER JOIN trading AS b ON u.stock_type = b.stock_type
      AND u.buying_selling != b.buying_selling
      AND u.bond = b.bond
LEFT JOIN users ON users.user_id = b.user_id
LEFT JOIN leads ON b.trade_id = leads.trade_id
WHERE u.user_id = @user_id
AND b.user_id != @user_id
AND u.timestamp > unix_timestamp(now() - interval 120 DAY)
AND b.timestamp > unix_timestamp(now() - interval 120 DAY)
GROUP BY
      b.trade_id
ORDER BY
      b.timestamp DESC

请注意,您依赖 MySQL 对分组查询的非标准支持,如果 sql_mode 更改为 only_full_group_by 我们的查询将会失败。在 MySQL 5.7.2 中,默认值是 only_full_group_by


0
投票

这是一个 CodeIgniter 脚本,用于将所有

u
->
b
表关系合并到 JOIN 的 ON 子句中。

构建 WHERE 子句时,关闭转义以防止 SQL 函数调用被视为字符串。

我建议永远不要从模型方法返回

false
,否则预计会返回一个数组。
result_array()
将返回零个或多个数组的数组。

function postsInterest(int $user_id): array
{
    return $this->db
        ->select('b.*, users.country, users.company, users.pic_small, users.subscription, COUNT(leads.user_id) leads')
        ->from('trading u')
        ->join('trading b', 'u.stock_type = b.stock_type AND u.bond = b.bond AND u.buying_selling != b.buying_selling AND u.user_id != b.user_id')
        ->join('users', 'b.user_id = users.user_id', 'LEFT')
        ->join('leads', 'b.trade_id = leads.trade_id', 'LEFT')
        ->where([
            'u.user_id' => $user_id,
            'u.timestamp >' => 'UNIX_TIMESTAMP(NOW() - INTERVAL 120 DAY)',
            'b.timestamp >' => 'UNIX_TIMESTAMP(NOW() - INTERVAL 120 DAY)'
        ], null, false)
        ->group_by('b.trade_id')
        ->order_by('b.timestamp', 'DESC')
        ->get()
        ->result_array();
}

渲染的SQL:

SELECT `b`.*, `users`.`country`, `users`.`company`, `users`.`pic_small`, `users`.`subscription`, COUNT(leads.user_id) leads
FROM `trading` `u`
JOIN `trading` `b` ON `u`.`stock_type` = `b`.`stock_type` AND `u`.`bond` = `b`.`bond` AND `u`.`buying_selling` != `b`.`buying_selling` AND `u`.`user_id` != `b`.`user_id`
LEFT JOIN `users` ON `b`.`user_id` = `users`.`user_id`
LEFT JOIN `leads` ON `b`.`trade_id` = `leads`.`trade_id`
WHERE u.user_id =  311
AND u.timestamp > UNIX_TIMESTAMP(NOW() - INTERVAL 120 DAY)
AND b.timestamp > UNIX_TIMESTAMP(NOW() - INTERVAL 120 DAY)
GROUP BY `b`.`trade_id`
ORDER BY `b`.`timestamp` DESC
© www.soinside.com 2019 - 2024. All rights reserved.