从MySQL表中选择子记录

3

我得到了下面这条select语句,它可以获取二级子记录,但是我想要更深层次的记录,有人能帮忙吗?

SELECT
  id_mobile AS ID_PROJETO,
  UM.qtd_UC,
  AM.qtd_AMBIENTE
FROM projetos_mobile AS PM
LEFT JOIN (
   SELECT
      COUNT(id) AS qtd_UC,
      projeto,
      data_hora_importacao,
      id_uc_mobile
   FROM ucs_mobile
   WHERE data_hora_importacao = '2015-05-15 17:21:02'
   GROUP BY projeto) AS UM
ON PM.id_mobile = UM.projeto
LEFT JOIN (
   SELECT
      COUNT(id_uc_mobile) AS qtd_AMBIENTE,
      id_uc_mobile
   FROM ucs_mobile
   LEFT JOIN (
      SELECT
         uc
      FROM ambientes_mobile AS s
      WHERE data_hora_importacao = '2015-05-15 17:21:02') AS G
   ON G.uc = ucs_mobile.id_uc_mobile
   WHERE data_hora_importacao = '2015-05-15 17:21:02') AS AM
ON UM.id_uc_mobile = AM.id_uc_mobile
WHERE PM.data_hora_importacao = '2015-05-15 17:21:02'

http://sqlfiddle.com/#!9/2eecf

如果有人想尝试解决方案,这里有一个 SQLFiddle。我有特定的层次结构:项目>使用者>环境>区域>测量。

ucs_mobile.projeto refers to projetos_mobile.id_mobile
ambientes_mobile.uc refers to ucs_mobile.id_uc_mobile
secoes_iluminacao_mobile.ambiente refers to ambientes_mobile.id_ambiente_mobile

我需要对传入的父级进行每个子级的计数,我将有5个函数返回给定父级的每个子级的计数,例如,对于项目父级,我应该有count(ucs),count(ambientes),count(secoes),count(medicoes)。
所以,希望你们能帮助我。数据库非常丑陋,但这就是我拥有的。感谢任何帮助。

感谢提供这个代码示例,但请问您对预期结果有何要求?另外,请不要使用默认值'0000-00-00',因为该值无法正确显示。建议尝试使用类似'0001-01-01'的数值来代替。 - AdamMc331
我需要对传入的父级别计算每个子级别的数量。我将有5个函数,返回给定父级别下每个子级别的数量,例如,对于项目(parent)应该有count(ucs),count(ambientes),count(secoes),count(medicoes)。 - Ricardo Silva
不用在意日期,这个问题在我开始处理之前就存在了。但还是谢谢你提醒我。 - Ricardo Silva
1个回答

1
当您有像这样非常大的查询时,将它们逐个拆分并从底层开始逐步修补起来通常会很有帮助。
我首先只是获取每个projetos_mobile值的ucs_mobile行数。您可以通过在相关行上连接两个表,并使用COUNT(DISTINCT um.id)来获得行数。还有其他方法可以实现,但是这种特定的方法对于查询的其余部分更具可扩展性。
SELECT pm.id, COALESCE(COUNT(DISTINCT um.id), 0) AS qty_uc
FROM projetos_mobile pm
LEFT JOIN ucs_mobile um ON um.data_hora_importacao = '2015-05-15 17:21:02' AND um.projeto = pm.id_mobile
GROUP BY pm.id;

使用 COALESCE 函数来填充 0 计数。只要记得使用 DISTINCT 关键字,并按适当的 id 进行分组,就可以像这样添加子行:
SELECT 
  pm.id, 
  COALESCE(COUNT(DISTINCT um.id), 0) AS qty_uc, 
  COALESCE(COUNT(DISTINCT am.id), 0) AS qty_am,
  COALESCE(COUNT(DISTINCT sim.id), 0) AS qty_sim
FROM projetos_mobile pm
LEFT JOIN ucs_mobile um ON um.data_hora_importacao = '2015-05-15 17:21:02' AND um.projeto = pm.id_mobile
LEFT JOIN ambientes_mobile am ON am.data_hora_importacao = um.data_hora_importacao AND am.uc = um.id_uc_mobile
LEFT JOIN secoes_iluminacao_mobile sim ON sim.data_hora_importacao = am.data_hora_importacao AND sim.ambiente = am.id_ambiente_mobile
GROUP BY pm.id;

这里有一个SQL Fiddle 示例。注意我稍微更改了你的样本数据,以确保我的查询按预期工作。
另外,顺便提一下。我注意到在你进行操作时,你不断使用相同的日期作为WHERE子句,所以我只是在每个表上加入了日期,并确保在我的第一个连接中查找指定的日期,这将传递到其他表中。

1
很棒的解决方案,它像魔法一样奏效。你让它看起来如此简单。感谢你的帮助。现在计算子级的子级数量将变得容易。 - Ricardo Silva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接