在mysql中从两个表中检索一对多关系的数据

时间:2016-07-18 14:17:13

标签: mysql select left-join

我有两张表RuleAction

一条规则可以有很多动作

让我们说Action有一个与一个规则相关的a1,a2,a3 3行

然后我想选择

r1.*, a1.name, a1.createdon, a1.modifiedon, 
      a2.name, a2.createdon, a2.modifiedon, 
      a3.name, a3.createdon, a3.modifiedon 

但是r2可能没有任何规则。 因此它将仅从Rule

中选择数据

结果

r*

我写了这个查询

SELECT * 
FROM Rule RB 
LEFT JOIN (
    SELECT RelatedRuleId
    FROM Action_ GROUP BY RelatedRuleId
) R ON R.RelatedRuleId =  RB.RuleId

这不能给我正确的结果。

我怎么拉这个?我想要一个规则行,同一行中有多个操作。

2 个答案:

答案 0 :(得分:1)

你可以通过简单的左连接来获得它

 SELECT RB.* ,
      GROUP_CONCAT(R.name), 
      GROUP_CONCAT(R.createdon),
      GROUP_CONCAT(R.modifiedon)
    FROM Rule RB 
    LEFT JOIN  Action R ON R.RelatedRuleId =  RB.RuleId 
    GROUP BY RB.RuleId

答案 1 :(得分:1)

在纯SQL中无法实现您想要的功能,因为在发出查询之前必须知道结果集中的列数。在您的要求中,列数由表的内容决定。这在SQL中是不可能的。

可以做什么,要么事先查询操作数,要么在应用程序代码中使用适当数量的列动态构建SQL,或者使用group_concat将结果连接到像这样的一栏:

select rule.id, 
       rule.name, 
       group_concat(concat(action.name, ';', 
                           action.createdon, ';', 
                           action.modifiedon)) as actions
from rule 
inner join action on rule.id = action.rule_id
group by rule.id

(另请参阅使用它的SQL小提琴http://sqlfiddle.com/#!9/94596/6

这会产生类似的结果:

id  name    actions
1   rule1   action1;2016-01-05;2016-02-06,action2;2016-01-06;2016-02-05
2   rule2   action3;2016-01-12;2016-02-19

然后,您需要通过在分隔符,;上拆分生成的列来解析它。