【问题标题】:uksort help - using GROUP BY in single need helpuksort help - 在单个需要帮助时使用 GROUP BY
【发布时间】:2011-09-29 04:01:34
【问题描述】:

您好,我有一个数组,通过uksort() 传递后看起来像这样

    Array
(
    [3] => Array
        (
            [job_id] => 4
            [job_title] => Supercar Test Driver
            [company_name] => McLaren
            [logo_small] => small_mclaren001.png
            [logo_large] => large_mclaren002.png
            [employer_id] => 3
        )

    [2] => Array
        (
            [job_id] => 3
            [job_title] => Recruitment Consultant - Driving
            [company_name] => MoovJob.com
            [logo_small] => small_rac001.png
            [logo_large] => large_rac002.png
            [employer_id] => 2
        )

    [1] => Array
        (
            [job_id] => 5
            [job_title] => Postal Worker / Post Person
            [company_name] => Royal Mail
            [logo_small] => small_royalmail001.png
            [logo_large] => large_royalmail002.png
            [employer_id] => 4
        )

    [0] => Array
        (
            [job_id] => 6
            [job_title] => Another Job
            [company_name] => MoovJob.com
            [logo_small] => small_rac001.png
            [logo_large] => large_rac002.png
            [employer_id] => 2
        )

)

但是,如果在返回此数组的 SQL 中添加 GROUP BY company_name 数组中的最终条目消失,我想要实现的是将职位放在公司名称下,但只显示公司名称一次,类似的东西,

公司名称 1
职称 1 职称 2 职称 3

公司名称 2
职位名称 4

公司名称
职称 5 职称 6

我正在尝试通过在我看来执行以下操作来实现这一点,但是我只能显示一个空缺,我做错了什么?

    <?php $oldemp   = "";?>
<?php foreach($jobs as $key => $value) : ?>
   <?php if ($oldemp != $value['company_name']) : ?>
        <?php $oldemp = $value['company_name']; ?>
        <section class="employer">
            <div class="job_holder">
                <img src="<?php echo base_url(); ?>media/uploads/users/<?php echo $value['logo_large']; ?>" width="198" height="148" alt="<?php echo $value['company_name']; ?>"/>
                <dl>
                    <dt><?php echo count($key); ?></dt>
                    <dd>Matches</dd>
                </dl>
    <?php endif;?>
            <span> + <a href="/jobwall/getjob/<?php echo $value['job_id']; ?>"><?php echo $value['job_title']; ?></a></span>
            </div>
        </section>
<?php endforeach; ?>


    function jobcmp($job1, $job2)
    {
        return strcmp($job1['company_name'], $job2['company_name']);
    }

【问题讨论】:

  • 这是一个很长的问题,有很多细节。这意味着任何人都需要付出很多努力才能理解核心问题,更不用说你的问题的细节了。如果您可以在更简单的情况下重新创建问题,然后要求我们解决简单的情况,这样我们就不必了解您的阵列的所有信息,这对我们和您都有帮助。
  • 你在uksort中使用了什么函数?
  • @glass 机器人请看我编辑的代码。

标签: php mysql arrays codeigniter foreach


【解决方案1】:

如果您显示 SQL 查询会有所帮助。不过消失的那一行显然和你添加的GROUP BY company_name有关。

当您添加GROUP BY groupfield 时,具有相同groupfield 的所有行“折叠”成一行。依赖于该字段的列,例如company_logo,通常可以安全地保留在SELECT 列表中。应删除或更改所有其他函数以使用 SUM()COUNT() 等聚合函数。

因此,如果您想显示每家公司的职位数量,请使用 COUNT(job_id)COUNT(*)

在你的情况下,我认为你有两个选择。

  • 第一个选项是不使用GROUP BY,也许只使用ORDER BY,并使用PHP 代码来显示您需要的内容。

  • 第二种选择是使用GROUP BY和聚合GROUP_CONCAT()函数。

你可以像这样使用它:

SELECT
    company_name
  , GROUP_CONCAT( job_id
                  ORDER BY job_id
                  SEPARATOR ', ' )
      AS job_ids
  , GROUP_CONCAT( job_title
                  ORDER BY job_id
                  SEPARATOR ', ' )
      AS job_titles
  , GROUP_CONCAT( CONCAT(job_id, '-', job_title)
                  ORDER BY job_id
                  SEPARATOR ', ' )
      AS job_ids_and_titles
  , company_name
  , logo_small
  , logo_large
  , employer_id
FROM 
  ...
GROUP BY company_name

【讨论】:

    【解决方案2】:

    你的数组排序不正确,相同id的员工应该是一个接一个,对于这个数组你应该使用这样的usort方法

    usort($jobs, function($a, $b) {
     if($a['employee_id'] == $b['employee_id'] return 0;
     return ($a['employee_id'] < $b['employee_id']) ? 1 : -1;
    })
    

    另一种方法,我认为更适合您的目的是使用 array_walk 为本节循环准备数据。下面的方法将从表中删除重复项,并将同一员工的所有 job_titles 连接到主要员工记录中的一个键中。

    array_walk($jobs, function($emp, $index) use(&jobs) {
      static $primary;
    
      if(isset($primary[$emp['employee_id']) {
        $jobs[$primary[$emp['employee_id']]]['job_titles'][$emp['job_id'] = $emp['job_title'];
        unset($jobs[$index]);
      } else {
        $primary[$emp['employee_id']] = $index; //remeber index of primary entry
      }
    });
    

    【讨论】:

    • 谢谢!然而,它现在正在输出雇主在其section 标签之外的第二份工作。这可以解决吗?
    • 生成
      节点的 if 语句中有错误的数据不是问题
    【解决方案3】:

    虽然可以使用您的方法显示数据,但我通常发现以更方便的格式创建第二个数组要简单得多:

    $groupedJobs = array();
    foreach ($jobs as $data) {
        if (!isset($groupedJobs[$data['company_name']])) {
            $groupedJobs[$data['company_name']] = array();
        }
        $groupedJobs[$data['company_name']][] = $data;
    }
    

    这将使用公司名称作为键创建一个新数组,并将嵌套数组中该公司的工作作为值,为您提供如下内容:

    ['MoovJob.com'] => Array
        (
            [0] => Array
                (
                    (job data)
                ),
            [1] => Array 
                (
                    (etc.)
                )
        ),
    ['McLaren'] = Array
        (
            (etc)
        )
    

    然后循环遍历这个数组并显示就容易多了:

    foreach ($groupedJobs as $companyName => $jobs) {
        echo $companyName;
        foreach ($jobs as $job) {
            echo $job['job_title'].'<br />';
        }
    }
    

    【讨论】:

    • 我不认为这个解决方案会更直接,但当然也可以使用不同的方法。
    • @Tim Fountain - 我可以吻你!
    【解决方案4】:

    看起来数组是按job_titleDESC排序的,而它应该按company_name排序

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      相关资源
      最近更新 更多