PHP&;MySQL:进行化学反应


PHP & MySQL: make chemical reaction

我有两个表1-tbl_reaction如下:

╔════╦═══════════╦════════════╦═════════╗
║ id ║ condition ║ phenomenon ║  infor  ║
╠════╬═══════════╬════════════╬═════════╣
║  1 ║ abcd123   ║ abcd123    ║ abcd123 ║
║  2 ║ wer       ║ wer        ║ wer     ║
╚════╩═══════════╩════════════╩═════════╝

2-tbl_reaction_item像这样:

╔══════╦═══════════╦═════════╦═════╗
║ reid ║ substance ║  type   ║ num ║
╠══════╬═══════════╬═════════╬═════╣
║    1 ║ H2        ║ income  ║   2 ║
║    1 ║ O2        ║ income  ║   1 ║
║    1 ║ H2O       ║ outcome ║   2 ║
╚══════╩═══════════╩═════════╩═════╝

什么是mysql查询显示反应:

收入+收入=结果

2H2+O2=>2H2O

mysql查询显示的反应是什么:(收入+收入=>结果)H2+O2=>H2O

SELECT CONCAT(GROUP_CONCAT(CASE WHEN type='income' THEN CONCAT(IF(num=1, '', num),substance) END SEPARATOR ' + '), ' => ',
             GROUP_CONCAT(CASE WHEN type='outcome' THEN CONCAT(IF(num=1, '', num),substance) END SEPARATOR ' + '))
             AS reaction
FROM tbl_reaction_item
GROUP BY reid;

SqlFiddleDemo

输出:

╔══════════════════╗
║     reaction     ║
╠══════════════════╣
║ 2H2 + O2 => 2H2O ║
╚══════════════════╝

工作原理:

  1. 利用GROUP_CONCAT和自定义分隔符' + '构建左侧和右侧
  2. 使用CONCAT=>连接双方
  3. 使用条件聚合分别获得收入/结果
  4. 使用IF函数删除num个1(也可以使用CASE

考虑使用GROUP_CONCAT(... ORDER BY pos):添加位置列以获得始终相同顺序的串联字符串部分

╔══════╦═══════════╦═════════╦═════╦══════╗
║ reid ║ substance ║  type   ║ num ║ pos  ║
╠══════╬═══════════╬═════════╬═════╬══════╣
║    1 ║ H2        ║ income  ║   2 ║   1  ║     -- hydrogen always first
║    1 ║ O2        ║ income  ║   1 ║   2  ║     -- second oxygen
║    1 ║ H2O       ║ outcome ║   2 ║   1  ║
╚══════╩═══════════╩═════════╩═════╩══════╝

附录

你应该改变你的模式。将主键添加到tbl_reaction_item,并使用reid作为外键。

SELECT t1.*, t2.reaction
FROM tbl_reaction t1
LEFT JOIN (
  SELECT reid, CONCAT(GROUP_CONCAT(CASE WHEN type='income' THEN CONCAT(IF(num=1, '', num),substance) END SEPARATOR ' + '), ' => ',
             GROUP_CONCAT(CASE WHEN type='outcome' THEN CONCAT(IF(num=1, '', num),substance) END SEPARATOR ' + '))
             AS reaction
  FROM tbl_reaction_item
  GROUP BY reid
) t2
  ON t1.id = t2.reid

SqlFiddleDemo2

输出:

╔═════╦════════════╦═════════════╦══════════╦══════════════════╗
║ id  ║ condition  ║ phenomenon  ║  infor   ║     reaction     ║
╠═════╬════════════╬═════════════╬══════════╬══════════════════╣
║  1  ║ abcd123    ║ abcd123     ║ abcd123  ║ 2H2 + O2 => 2H2O ║
║  2  ║ wer        ║ wer         ║ wer      ║ (null)           ║
╚═════╩════════════╩═════════════╩══════════╩══════════════════╝

我喜欢lad的SQL解决方案,但您也可以使用PHP。请注意,我还没有测试过它,并且认为我在添加字符串时有一个错误,但你已经明白了。

$income=[];
$outcome=[];
$stmt=$conn->prepare('SELECT substance,type,num FROM tbl_reaction_item WHERE reid=?');
$stmt->execute(array(1));
while($row=$stmt->fetch()){
    if($row->type=='income') {$income[]=$row->num+$row->substance;}
    else {$outcome[]=$row->num+$row->substance;}
}
echo(implode(' + ',$income).' => '.implode(' + ',$outcome));