我有 3 个表,需要制作一个漂亮的平滑 SELECT,它可以从所有这些表中返回我的数据。
表格如下所示:
例
------------------------------------------------------
| id | case_id | country | vin |
------------------------------------------------------
| 22 | 9856 | US | VF7S6NFZF56215577 |
------------------------------------------------------
| 23 | 9857 | GB | GF7S6NFZF56215579 |
------------------------------------------------------
| 23 | 9858 | US | VF7S6NFZF56215577 |
------------------------------------------------------
计算
---------------------------------------------------------------------
| calculation_id | case_id | totalcosts | currency |
---------------------------------------------------------------------
| 95 | 9856 | 78945 | USD |
---------------------------------------------------------------------
| 96 | 9856 | 12345 | USD |
---------------------------------------------------------------------
| 97 | 9857 | 23986 | XTB |
---------------------------------------------------------------------
| 98 | 9858 | 77896 | USD |
---------------------------------------------------------------------
正位素
--------------------------------------------------------------------------
| calculation_id | case_id | text | method | guide | position_id
---------------------------------------------------------------------------
| 95 | 9856 | textAB | E | N/A | 11 |
---------------------------------------------------------------------------
| 96 | 9856 | textAB | E | N/A | 22 |
---------------------------------------------------------------------------
| 96 | 9856 | textAC | L | N/A | 3 |
---------------------------------------------------------------------------
| 96 | 9856 | textAD | E | Y | 8 |
---------------------------------------------------------------------------
| 97 | 9856 | textAE | E | N/A | 11 |
---------------------------------------------------------------------------
这就是结果的样子(这是 rest API 的一部分,所以我将提供 JSON)
[
{
caseId:9856,
country:'US',
totalcosts:12345,
currency:'USD',
positions:[
{
method:'E',
guide:'N/A',
positionId:22,
text:'TextAB'
},
{
method:'L',
guide:'N/A',
positionId:3,
text:'TextAC'
} {
method:'E',
guide:'Y',
positionId:8,
text:'TextAD'
}
]
},
{
caseId:9858,
country:'US',
totalcosts:77896,
currency:'USD',
positions:[
]
}
]
反应的消耗:
- 案例:用户始终提供VIN号和查询需要收集其余数据。重要的是,每个 vin 可以有多个案例。应该始终提供所有这些。
- 计算:每种情况可以有多个计算。总是最后一个很重要(该case_id calculation_id最高的那个)。
- 位置:只需在此处提取数据
我试了什么:
SELECT c.case_id, c.country, cl.totalcosts, cl.currency,
GROUP_CONCAT(DISTINCT po.text ORDER BY 1) AS texts,
GROUP_CONCAT(DISTINCT po.part_position_id ORDER BY 1) AS partIds,
GROUP_CONCAT(DISTINCT po.guidenumber ORDER BY 1) AS guideNumbers
FROM cases
LEFT JOIN calculations as cl on c.case_id = cl.case_id AND c.country = cl.country
LEFT JOIN axnmrs_positions as po on c.case_id = po.case_id AND cl.calculation_id = po.calculation_id
这个选择背后的想法是,我将位置表中的所有数据分组,然后在我的 php 文件中,我将用逗号 (,
分解所有这些数据。
我认为这是可能的解决方案,但真的很丑陋,我敢打赌它也不是性能问题的最佳选择。
谁能想到更好的解决方案来解决这种情况? 多谢!
附言所有表格和查询都进行了简化,以保持这个问题清晰。对于可能的错别字,我很抱歉
由于您没有告诉我们有关此处的基数/外键约束的任何信息,例如如何处理数字计算,因此这变得更加复杂
所以我不能告诉你你的查询应该是什么样子。
我同意以这种方式使用 GROUP_CONCAT() 是丑陋的。
因此,使用一个名为"header"的关系和一个名为"detail"的关系之间的 1:m 关系的更简单示例......
SELECT h.id, h.date, h.other,
d.type, d.unit_cost, d.quantity
FROM header h
LEFT JOIN detail d
ON h.id=d.header_id
WHERE ds.date
;
$output=array();
while ($r=mysqli_fetch_assoc($result)) {
extract($r);
if (!is_array($output[$id])) {
$output[$id]=array(
'date'=>$date, 'other'=>$other,
'detail'=>array());
}
if ($type) {
$output[$id]['detail'][]=array(
'type'=>$type, 'unit_cost'=>$unit_cost,
'quantity'=>$quantity);
}
}
print json_encode($output);
如果要包含没有详细信息的标头记录,则需要LEFT JOIN
和if ($type) {
。