为什么将count(*)作为名称显示未定义索引:名称

时间:2019-03-27 21:19:02

标签: php mysql database

从数据库php获取数据时,说该行的未定义索引为count(*),即未定义的名称

SELECT location.location_name,
       employers.emp_name,
       (SELECT COUNT(present.present_date) AS present_days
        from present
        WHERE present_status='م' AND present.emp_id=employers.emp_id AND present.present_date between '$date1' AND '$date2') ,
       (SELECT COUNT(present.present_status) AS absent_days 
        from present
        WHERE present_status='غ' AND present.emp_id=employers.emp_id AND present.present_date between '$date1' AND '$date2'), 
       (SELECT COUNT(present.present_status) AS permission_absent_days
        from present
        WHERE present_status='غب' AND present.emp_id=employers.emp_id AND present.present_date between '$date1' AND '$date2'),
       (SELECT band.band_name AS training
        from band
        WHERE band_name='NoTraining' AND band.emp_id=employers.emp_id AND band.band_date between '$date1' AND '$date2'),
       (SELECT COUNT(band.band_name)AS employers_band
        from band
        WHERE band.emp_id=employers.emp_id AND band.band_date between '$date1' AND '$date2') 
FROM `present`, `employers`,`location`,`band`
WHERE  present.emp_id = employers.emp_id AND location.location_id = employers.location_id 
GROUP BY employers.emp_name 
ORDER BY employers.emp_name ASC

1 个答案:

答案 0 :(得分:1)

别名分配应在 SELECT列表中子查询的结束括号之后

SELECT ...
     , ( SELECT ... AS foo FROM ... WHERE ... ) AS col_name
--                                              ^^^^^^^^^^^
  FROM 

在子查询中分配的别名foo与外部查询无关。对于外部查询重要的是为外部查询col_name的SELECT列表中的表达式分配的别名。

(我们可以在mysql命令行客户端中运行查询,并在结果集中查看分配给该列的内容。或者在PHP代码中,我们可以检查/ vardump从访存中返回的数组。)


其他一些问题似乎是半笛卡尔积,从多个子表返回的多行交叉连接在一起。似乎缺少某些加入条件。

我建议放弃用于联接操作的老式逗号语法,而改用JOIN关键字。


关注

以上建议(在外部查询的SELECT列表中为子查询表达式分配别名可能会“起作用”,但我认为查询存在更多错误。

有了SELECT列表中的相关子查询,我认为没有必要在外部查询中执行对bandpresent的联接。当返回多行并交叉连接时,这将产生奇怪的结果。而且,如果bandpresent没有返回匹配行,则结果集中将丢失一行。

在我看来(我只是在猜测,因为我们没有该查询应返回的规范)...

在我看来,其意图是返回与该模式的查询返回的结果相同的结果:

SELECT l.location_name
     , e.emp_name

     , ( SELECT COUNT(pd.present_date) AS present_days
           FROM present pd
          WHERE pd.emp_id         = e.emp_id
            AND pd.present_status = '?'
            AND pd.present_date   BETWEEN '$date1' AND '$date2'
       ) AS present_days

     , ( SELECT COUNT(ad.present_status)
           FROM `present` ad
          WHERE ad.emp_id         = e.emp_id
            AND ad.present_status = '?'
            AND ad.present_date   BETWEEN '$date1' AND '$date2'
       ) AS absent_days

    , ( SELECT COUNT(pa.present_status)
          FROM `present` pa
         WHERE pa.emp_id          = e.emp_id
           AND pa.present_status  = '??'
           AND pa.present_date    BETWEEN '$date1' AND '$date2'
       ) AS permission_absent_days

    , ( SELECT MAX(tr.band_name)
          FROM `band` tr
         WHERE tr.emp_id          = e.emp_id
           AND tr.band_name       = 'NoTraining'
           AND tr.band_date       BETWEEN '$date1' AND '$date2'
      ) AS training

    , ( SELECT COUNT(eb.band_name)
          FROM `band` eb
         WHERE eb.emp_id          = e.emp_id
           AND eb.band_date       BETWEEN '$date1' AND '$date2'
      ) AS employers_band

  FROM `employers` e
  JOIN `location` l
    ON l.location_id = e.location_id
 ORDER
    BY e.emp_name ASC