我正在通过2个mysql表格中的php生成PDF,其中包含一个表格。在较大的表上,脚本占用了大量内存,并开始成为一个问题。
我的第一张表包含“检查”。每天有很多行。这与用户表有多对一的关系。
表“检查”
id(int)
area(varchar) - 是8个“区域”之一,即:混凝土,土壤,土方工程
inspection_date(int) - unix时间戳
inspection_agent_1(int) - 用户ID
inspection_agent_2(int) - 用户ID
inspection_agent_3(int) - 用户ID
最终表格将在PDF中,需要通过以下方式组织数据:
混凝土
土壤
土方
2011年1月18日
Jon Doe
X
简·多伊
X
X
等等每一天。现在我只是对名称进行简单连接,然后在代码端组织所有内容。我知道,就查询而言,我会在桌子上留下很多东西,我只是想不出办法去做。
感谢您的帮助。
答案 0 :(得分:1)
我会这样:
select i.*, u1.name, u2.name, u3.name from inspections i left join users u1 on (i.inspection_agent_id1 = u1.id) left join users u2 on (i.inspection_agent_id2 = u2.id) left join users u3 on (i.inspection_agent_id3 = u3.id) order by i.inspection_date asc;
然后选择不同的区域名称并记住它们,或者如果您有任何区域,则从区域表中获取它们:
从检查中选择不同的区域;
然后它就是foreach:
$day = "";
foreach($inspection in $inspections)
{
if($day == "" || $inspection["inspection_date"] != $day)
{
//start new row with date here
}
//start standard row with user name
}
目前尚不清楚您是否必须每次都显示所有用户(即使其中一些用户没有进行检查),如果必须,您应该获取用户一次并循环$ users并搜索用户$ inspection row。
答案 1 :(得分:1)
Select U.name
, user_inspections.inspection_date
, Min( Case When user_inspections.area = 'Concrete' Then 'X' End ) As Concrete
, Min( Case When user_inspections.area = 'Soils' Then 'X' End ) As Soils
, Min( Case When user_inspections.area = 'Earthwork' Then 'X' End ) As Earthwork
From users As U
Join (
Select area, inspection_date, inspection_agent1 As user_id
From inspections
Union All
Select area, inspection_date, inspection_agent2 As user_id
From inspections
Union All
Select area, inspection_date, inspection_agent3 As user_id
From inspections
) As user_inspections
On user_inspections.user_id = U.id
Group By U.name, user_inspections.inspection_date
这实际上是一个静态交叉表。这意味着您需要知道在设计时应该在查询中输出的所有区域。
此查询存在问题的原因之一是您的架构未规范化。您的检查表应如下所示:
Create Table inspections
(
id int...
, area varchar...
, inspection_date date ...
, inspection_agent int References Users ( Id )
)
这样可以避免内部的Union All查询获得所需的输出。