PHP& MySQL:做出化学反应

时间:2016-01-09 15:36:41

标签: php mysql sql

我有2张桌子 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

2 个答案:

答案 0 :(得分:5)

  

什么是mysql查询来显示这样的反应:(收入+   收入=>结果)H2 + O2 => H 2 O

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. 使用条件聚合分别获得收入/结果
  5. 使用1功能删除num IF(也可以使用CASE
  6. 考虑使用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)           ║
    ╚═════╩════════════╩═════════════╩══════════╩══════════════════╝
    

答案 1 :(得分:0)

我喜欢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));