【问题标题】:MySQL PDO - latest row for table grouped with joinsMySQL PDO - 用连接分组的表的最新行
【发布时间】:2019-01-16 00:11:32
【问题描述】:

对于标题描述,我深表歉意,因为我不确定如何最好地描述这一点。

有多台计算机,每台计算机有多个用户,每个用户有多个数据日志。我想获取每台计算机的最新数据日志。

我现在意识到下面的查询没有提供正确的数据,因为 ORDER BY 发生在结果中,而 GROUP BY 没有特定的顺序。

我在发布此内容之前确实阅读了此内容,似乎需要一个子查询,然后在同一张表上再次加入该结果以获取其余行列值(发现是最新的那个) .我发现的示例虽然非常基本,但不涉及连接其他表。似乎我还必须这样做两次,因为我希望它按计算机分组......(一次用于按 user_id 分组的 data_logs 并获得最大值,然后另一个按 computer_id 分组以获得早期结果的最大值)或者我在那里错了.

需要一些帮助来掌握如何解决这个问题以及解决方法。

$stmt = $db->prepare("
    SELECT
        computers.computer_name,
        users.username,
        data_logs.window_title,
        data_logs.filename,
        data_logs.capture_timestamp
    FROM computers
    INNER JOIN users
        ON users.computer_id = computers.computer_id
    INNER JOIN data_logs
        ON data_logs.user_id = users.user_id AND data_logs.marked != 1
    WHERE computers.account_id = :cw_account_id AND computers.status = 1
    GROUP BY computers.computer_id
    ORDER BY data_logs.capture_timestamp desc
");

$binding = array('cw_account_id' => 1721);
$stmt->execute($binding);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

echo "<pre>";
print_r($results);
echo "</pre>";

【问题讨论】:

    标签: mysql pdo group-by sql-order-by greatest-n-per-group


    【解决方案1】:

    一种解决方案是使用相关子查询。原理是外层查询不聚合,但在WHERE子句中有一个条件,选择当前计算机id的最新日志条目,使用聚合子查询。

    我猜你会需要这个查询(虽然没有看到样本数据和预期的输出,这可能不是 100% 准确):

    SELECT
        computers.computer_name,
        users.username,
        data_logs.window_title,
        data_logs.filename,
        data_logs.capture_timestamp
    FROM computers
    INNER JOIN users
        ON users.computer_id = computers.computer_id
    INNER JOIN data_logs
        ON data_logs.user_id = users.user_id AND data_logs.marked != 1
    WHERE 
        computers.account_id = :cw_account_id 
        AND computers.status = 1
        AND data_logs.capture_timestamp = (
            SELECT MAX(d.capture_timestamp)
            FROM computers c
                    INNER JOIN users u ON u.computer_id = c.computer_id
            INNER JOIN data_logs d ON d.user_id = u.user_id AND d.marked != 1
            WHERE c.computer_id = computers.computer_id AND c.account_id = computers.account_id
        )
    ORDER BY data_logs.capture_timestamp desc
    

    【讨论】:

    • 可以有多台计算机,每台计算机有多个用户,每个用户有多个数据日志。从我在这里看到的情况来看,它只会为提供的特定“帐户”(:cw_account_id)选择一条记录,而不是每台计算机选择一条记录。
    • 我收回了……看起来这是在提取正确的信息,并且是每台计算机上的最新信息。将需要使用实时数据对此进行更多测试并比较结果,但我对此抱有希望:)
    • @user756659 :我更新了子查询以在 account_id 上包含一个过滤器。
    • 这有必要吗,因为它已经被列为 where 语句的第一项?
    • 是 @user756659 我认为这是必要的,子查询必须与外部查询相关....您能否测试查询并告诉我它是否有效适合你吗?
    猜你喜欢
    • 1970-01-01
    • 2014-10-28
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2023-03-24
    • 1970-01-01
    • 2013-08-08
    相关资源
    最近更新 更多