正在寻找一些帮助,但发现了一些帮助,但当 FROM 也是子查询时却一无所获。
SELECT COUNT(*)
FROM
( SELECT tc.*,
( SELECT status FROM test_case_executions tce
WHERE tce.test_case_id = tc.id
ORDER BY tce.execution_date DESC, tce.id DESC LIMIT 1
) AS last_status FROM test_cases tc
) a
WHERE a.last_status = '$status'
CI 有没有办法只使用它并执行它,或者有人可以帮助我按照 CI 想要的方式编写它?
您需要的一切都可以在这里找到,正如上面评论中提到的。为了帮助您入门,您可以这样做:
$this->db->query("
SELECT COUNT(*) AS amount
FROM ( SELECT tc.*,
( SELECT status
FROM test_case_executions AS tce
WHERE tce.test_case_id = tc.id
ORDER BY tce.execution_date DESC, tce.id DESC
LIMIT 1) AS last_status
FROM test_cases AS tc
) AS a
WHERE a.last_status = ?
", array($status));
基本上评论都是这么说的。是什么让这比简单的
mysql_query
等更“CI 方便”,是因为你可以转义传递的值以摆脱错误和 sql 注入。请注意最后一部分 ?
和第二个参数 array($status)
。我还设计了这个查询的样式,使其更容易被眼睛看到(imo)。
您可能会想“但是我想使用 Active Records!D:”,但是更高级的东西需要您离开舒适区。祝你好运!
我不同意@Anusha的观点,即构建这个嵌套查询结构是“复杂的”。 只需使用查询生成器方法从最里面的子查询构建出来,然后根据需要将构建的查询插入到其父查询中。
我建议调整 SQL 以避免 SELECT 子句中的子查询,而不仅仅是将发布的 SQL 转换为查询构建器调用,而这些子查询往往性能不佳。
我建议加入一个子查询,该子查询按 id 对测试用例进行分组并返回最新的执行日期,然后将执行表加入到该派生表中,以便能够访问每个测试用例的last_status,按传入的状态过滤它们,并计算总计。
public function countTestCasesByStatus(string $status): int
{
$latestExecutionPerId = $this->db
->select('tc.id, MAX(tce.execution_date) last_execution_date')
->join('test_case_executions tce1', 'tc.id = tce.test_case_id')
->group_by('tc.id')
->get_compiled_select('test_cases tc');
return $this->db
->join('test_case_executions tce2', 'lepi.id = tce2.test_case_id AND lepi.last_execution_date = tce2.execution_date')
->where('tce2.status', $status)
->count_all_results("($latestExecutionPerId) lepi");
}
渲染的 SQL(假设输入字符串为
foo
):
SELECT COUNT(*) AS `numrows`
FROM (
SELECT `tc`.`id`, MAX(tce.execution_date) last_execution_date
FROM `test_cases` `tc`
JOIN `test_case_executions` `tce1` ON `tc`.`id` = `tce`.`test_case_id`
GROUP BY `tc`.`id`
) lepi
JOIN `test_case_executions` `tce2` ON `lepi`.`id` = `tce2`.`test_case_id` AND `lepi`.`last_execution_date` = `tce2`.`execution_date`
WHERE `tce2`.`status` = 'foo'