Mysql 需要使用联接来检索总和的帮助,或者如果不存在条目,则需要从右表中获取0

Mysql 需要使用联接来检索总和的帮助,或者如果不存在条目,则需要从右表中获取0,mysql,left-join,Mysql,Left Join,我需要一些关于以下问题的帮助。我肯定我想得太多了,但我想: SELECT bc.name, bc.category_id, bc.ref_id, COALESCE(bc.parent_id,bc.category_id) as parent_category_id, (select name FROM budget_categories bc2 WHERE bc2.category_id = bc.par

我需要一些关于以下问题的帮助。我肯定我想得太多了,但我想:

    SELECT 
        bc.name, 
        bc.category_id,
        bc.ref_id,
        COALESCE(bc.parent_id,bc.category_id) as parent_category_id,
        (select name FROM budget_categories bc2 WHERE bc2.category_id = bc.parent_id) as parent_name,
        (select ref_id FROM budget_categories bc2 WHERE bc2.category_id = bc.parent_id) as parent_ref_id, 
        COALESCE(sum(bee.amount),0) as amount
    FROM 
        budget_expected_expenses bee, budget_categories bc 
    WHERE 
        bc.group_id IN (1,139) AND
        bee.group_id = 1 AND
        bee.date BETWEEN '2012-01-01' AND '2012-01-31' AND 
        bee.cat_id = bc.category_id 
    GROUP BY bee.cat_id ORDER BY bc.ref_id ASC
基本上,目标是返回“bc”表中每个类别的总和,无论是由集团还是总部创建的——在本例中,分别是“bee”表中的1和139。如果特定组的“bee”中没有条目,我需要它返回0。但是,此查询仅返回“bee”表中实际有条目的值的总和。我肯定我错过了一些东西,但是,嗯,我错过了。提前谢谢

注意:我尝试了各种连接,但似乎没有任何效果。显然这是可能的,我只是空白

FROM budget_expected_expenses bee, budget_categories bc 
如果希望条目出现在bc中,但不一定是bee,请执行左连接:

FROM budget_categories bc LEFT JOIN budget_expected_expenses bee ON bc.category_id = bee.cat_id
您还需要按保证不为null的列进行分组:

GROUP BY bc.category_id
此外,由于交叉连接和复杂的子查询,您的查询比需要的复杂得多。您可以将其简化为以下内容:

SELECT 
    bc.name, 
    bc.category_id,
    bc.ref_id,
    COALESCE(bc.parent_id,bc.category_id) as parent_category_id,
    parent.name as parent_name,
    parent.ref_id as parent_ref_id, 
    COALESCE(sum(bee.amount),0) as amount
FROM 
    budget_categories bc
LEFT JOIN
    budget_expected_expenses bee ON bc.category_id = bee.cat_id
LEFT JOIN
    budget_categories parent ON bc.parent_id = parent.category_id
WHERE 
    bc.group_id IN (1,139) AND
    bee.group_id = 1 AND
    bee.date BETWEEN '2012-01-01' AND '2012-01-31'
GROUP BY bc.category_id ORDER BY bc.ref_id ASC

建议您重写查询,使其具有左联接:

SELECT 
    ....
    COALESECE(SUM(bee.amount,0.00))
FROM
    budget_categories bc 
    LEFT JOIN
    budget_expected_expenses bee ON bee.cat_id = bc.category_id
WHERE 
    ...

左联接将始终以联接左侧的每条记录至少一条结果记录结束。如果没有匹配的右侧记录,将使用NULL,这就是为什么需要合并将其转换为0.00。

I'v使用比旧的列表表格式更新的ANSI样式重写,并在WHERE子句中显式添加连接条件。通过这种方式,您应该更好地了解每个表与其他表之间的关系,以及希望应用于这些连接元素的明确限制,例如日期条件。where子句只保留select的第一个表中的条件

我对category表应用了两个连接,一次是基于您查找父类别以及名称和引用ID的意图,前提是父ID存在。如果没有,它将查看找到的默认类别ID

我认为我看到的唯一问题是加入预期费用,其中您的标准仅为group_ID=1,而您的预算类别标准为1或139 via in子句。如果它们实际上应该是相同的,则将联接调整为

和bc.group\u ID=bee.group\u ID

最后,确认您想要按…分组的内容。。。原始类别,或与其关联的父类别,但这也是您的呼叫

SELECT 
      bc.name, 
      bc.category_id,
      bc.ref_id,
      COALESCE( bc.parent_id,bc.category_id) as Which_Category_id,
      COALESCE( bcParent.Name, bcDefCat.Name ) as Category_Name,
      COALESCE( bcParent.Ref_ID, bcDefCat.Ref_ID ) as Category_Ref_ID,
      COALESCE(sum(bee.amount),0) as amount
    FROM 
        budget_categories bc 

           LEFT JOIN budget_expected_expenses bee
              ON bc.category_id = bee.cat_id
              AND bee.group_ID = 1
              AND bee.date BETWEEN '2012-01-01' AND '2012-01-31' 

           LEFT JOIN budget_categories bcParent
              on bc.parent_ID = bcParent.category_ID

           JOIN budget_categories bcDefCat
              on bc.Category_ID = bcDefCat.category_ID
   WHERE 
      bc.group_id IN (1,139) 
   GROUP BY 
      bc.category_id 
   ORDER BY 
      bc.ref_id ASC