我正在获取所有被批准和未存档的员工的id,名字和姓氏。 然后我在循环这些结果,并使用id来查询其他表来收集一些计数数据。
我尝试了下面的代码,但我没有得到预期的输出。
$queryEmp = "
SELECT id, firstname, lastname
FROM tbl_employee as e
WHERE is_archive=0 and is_approved=1
";
$getQuery= $this->db->query($queryEmp);
$result= $getQuery->result();
foreach ($result as $key=> $value) {
//echo "<pre>";
print_r($value);
$day = "MONTH(date_of_created) = DATE(CURRENT_DATE())";
$group = "f_id IN (SELECT MAX(f_id) FROM tbl_fileStatus GROUP BY f_bankid)";
$condiion = "and ba.createdby='" . $value->id . "' and " . $day ." and " . $group;
$query2 = "
select
(SELECT COUNT(c_id)
FROM tbl_lead
WHERE leadstatus='1' AND ".$day.") as confirmCount,
(SELECT COUNT(f_id)
FROM tbl_fileStatus as fs
join tbl_bankdata as ba on ba.bank_id=fs.f_bankid
WHERE fs.f_filestatus=1 " . $condiion . ") as disbursed,
(SELECT COUNT(f_id)
FROM tbl_fileStatus as fs
join tbl_bankdata as ba on ba.bank_id=fs.f_bankid
WHERE fs.f_filestatus=2 ".$condiion.") as filesubmit
";
# code...
$getQuery2= $this->db->query($query2);
$result2[]=$getQuery2->result();
}
echo "<pre>";
print_r(result2);
$result
看起来是这样的。
Array (
[0] => stdClass Object (
[id] => 1
[firstname] => xyz
[lastname] => xyz
)
...
)
第二次查询输出。
Array (
[0] => Array (
[0] => stdClass Object (
[fallowCall] => 0
[confirmCount] => 0
[disbursed] => 0
[filesubmit] => 0
)
)
...
)
我怎样才能产生正确的结果,将员工的业绩指标与他们的业绩指标联系起来? 要么是这个结构。
Array (
[0] => stdClass Object (
[id] => 1
[firstname] => xyz
[lastname] => xyz
[somename] => (
[fallowCall] => 0
[confirmCount] => 0
[disbursed] => 0
[filesubmit] => 0
)
)
...
)
或者是这个结构
Array (
[0] => stdClass Object (
[id] => 1
[firstname] => xyz
[lastname] => xyz
[fallowCall] => 0
[confirmCount] => 0
[disbursed] => 0
[filesubmit] => 0
)
...
)
我在这里添加了我的表结构和一些示例数据。https:/www.db-fiddle.comf8MoWmKPuzTrrC3DQJsiX350
附注
1) createdby
是表的id tbl_employee
2) lead_id
在银行表里是 c_id
桌子的 tbl_lead
3) f_bankid
在 tbl_fileStatus
是 bank_id
桌子的 tbl_bankdata
其实没有必要为了保存计数数据而创建额外的深度复杂度。 此外,通过使用LEFT JOINs组合来连接相关的表,并应用你所需要的条件规则,你只需对数据库进行一次访问,就可以达到你想要的结果。 毫无疑问,这将为您的应用提供卓越的效率。 LEFT JOINs的使用非常重要,这样可以使计数为零而不至于将雇员从结果集中排除。
另外,我应该指出,你的尝试查询是错误地比较了一个 MONTH()
比值 DATE()
值 -- 这绝对不会有好的结果 :) 事实上,为了确保你的sql能够准确地将当前月份与当前年份隔离开来,你需要同时检查YEAR值。
我推荐的sql。
SELECT
employees.id,
employees.firstname,
employees.lastname,
COUNT(DISTINCT leads.c_id) AS leadsThisMonth,
SUM(IF(fileStatus.f_filestatus = 1, 1, 0)) AS disbursedThisMonth,
SUM(IF(fileStatus.f_filestatus = 2, 1, 0)) AS filesubmitThisMonth
FROM tbl_employee AS employees
LEFT JOIN tbl_lead AS leads
ON employees.id = leads.createdby
AND leadstatus = 1
AND MONTH(leads.date_of_created) = MONTH(CURRENT_DATE())
AND YEAR(leads.date_of_created) = YEAR(CURRENT_DATE())
LEFT JOIN tbl_bankdata AS bankData
ON employees.id = bankData.createdby
LEFT JOIN tbl_fileStatus AS fileStatus
ON bankData.bank_id = fileStatus.f_bankid
AND MONTH(fileStatus.date_of_created) = MONTH(CURRENT_DATE())
AND YEAR(fileStatus.date_of_created) = YEAR(CURRENT_DATE())
AND fileStatus.f_id = (
SELECT MAX(subFileStatus.f_id)
FROM tbl_fileStatus AS subFileStatus
WHERE subFileStatus.f_bankid = bankData.bank_id
GROUP BY subFileStatus.f_bankid
)
WHERE employees.is_archive = 0
AND employees.is_approved = 1
GROUP BY employees.id, employees.firstname, employees.lastname
我推荐的SQL语句是: SUM(IF())
表达式是一种用于执行 "条件统计 "的技术。 "汇总数据 "是用GROUP BY形成的,有专门的"汇总函数",必须用它来从这些簇非平坦的数据集合中创建线性平坦数据。 fileStatus
由于GROUP BY调用,数据有效地堆积在自己身上。 如果 COUNT(fileStatus.f_filestatus)
被调用,它将计算集群中的所有行。 由于您希望区分 f_filestatus = 1
和 f_filestatus = 2
,一个 IF()
语句的使用。 这与 COUNT()
(每出现一次合格的情况,就加1),但它不同于 COUNT()
因为它不计算特定的行(在集群的范围内),除非是 IF()
表达式得到满足。 另一个例子.
这里是一个db fiddle演示与一些调整你提供的样本数据。https:/www.db-fiddle.comf8MoWmKPuzTrrC3DQJsiX354 结果集只能是 "好",而当前是今年6月)。
将上述字符串保存为 $sql
你可以简单地执行它,并像这样在对象数组中循环。
foreach ($this->db->query($sql)->result() as $object) {
// these are the properties available in each object
// $object->id
// $object->firstname
// $object->lastname
// $object->leadsThisMonth
// $object->disbursedThisMonth
// $object->filesubmitThisMonth
}