【问题标题】:How to query employee details and relate their performance metrics?如何查询员工详细信息并关联他们的绩效指标?
【发布时间】:2020-09-10 14:14:51
【问题描述】:

我正在获取所有已批准但未归档的员工的 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.com/f/8MoWmKPuzTrrC3DQJsiX35/0

这里有一些注意事项

1)createdby是表tbl_employee的id

2) 银行表中的lead_id 是表tbl_leadc_id

3)tbl_fileStatus中的f_bankid是表tbl_bankdatabank_id

【问题讨论】:

  • @mickmackusa,“多维结构?” 因为我正在获取员工详细信息,在第二个查询中,我有一些与员工相关的详细信息以及我必须在列表中显示的所有详细信息。所以我认为我的期望可以帮助我解决
  • 到目前为止,我的计数为零。这是一个例子。关于so​​mename,我认为这将是一个好方法。我也可以使用此输出 [0] => stdClass Object ( [id] => 1 [firstname] => xyz [lastname] => xyz [fallowCall] => 0 [confirmCount] => 0 [disbursed] => 0 [文件提交] => 0)
  • @mickmackusa,在您的第一个查询中,我收到错误 #1242 - 子查询返回多于 1 行。我认为如果我们使用数组,那么它会很好,并且有更多的变化来增加将来的子查询。
  • @mickmackusa,我创建了表格结构并在问题中进行了更新。
  • 请提供足够的小提琴数据以生成非零计数。将合格数据和不合格数据混合用于预期查询,可以更轻松地测试/可视化验证“工作解决方案”。 (然后更新演示链接。)另外请删除此问题下对研究人员/志愿者没有未来价值的旧 cmets。我的工作日在 3 小时后结束,我会回来查看。

标签: php sql codeigniter join multidimensional-array


【解决方案1】:

实际上没有必要仅仅为了保存计数数据而创建额外的深度/复杂度。此外,通过使用 LEFT JOIN 组合来连接相关表并应用所需的条件规则,您只需访问数据库一次即可获得所需的结果。毫无疑问,这将为您的应用程序提供卓越的效率。使用 LEFT JOIN 很重要,这样计数可以为零,而不会将员工排除在结果集中。

另外,我应该指出,您尝试的查询错误地将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

SUM(IF()) 表达式是一种用于执行“条件计数”的技术。 “聚合数据”是通过使用 GROUP BY 形成的,并且必须使用专门的“aggregate functions”从这些集群/非平面数据集合中创建线性/平面数据。 fileStatus 数据由于 GROUP BY 调用而有效地堆积在自身上。如果调用COUNT(fileStatus.f_filestatus),它将计算集群中的所有行。由于您希望区分f_filestatus = 1f_filestatus = 2,因此使用IF() 语句。这与COUNT() 做同样的事情(为每个符合条件的事件添加1),但它与COUNT() 的不同之处在于它不计算特定行(在集群范围内),除非IF() 表达式是使满意。 Another example.

这是一个 db fiddle 演示,对您提供的示例数据进行了一些调整:https://www.db-fiddle.com/f/8MoWmKPuzTrrC3DQJsiX35/4(结果集只会是“好”,而当前是今年 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
}

【讨论】:

  • 非常感谢您的回答,非常感谢您对更好问题的支持和指导。答案对我有用。我还没有理解这个 fileStatus.f_filestatus = 1, 1, 0)。如果可能的话,你可以分享任何我可以学习的链接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-31
  • 2020-10-08
  • 1970-01-01
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多