合并的使用

Usage of COALESCE

我有一个查询使用 COALESCE() 来计算 2 列的组合:

SELECT method, main_ingredient, COUNT(*) AS cnt FROM  `recipes` 
GROUP BY COALESCE( method, main_ingredient ) 

结果有用。示例结果:

method    main_ingredient    cnt
================================
     1    4                  10
     2    1                  6
     3    6                  3
     4    6                  5
     5    2                  4
     6    8                  2

但是,如何获得 COUNT(*) 等于 0 的结果?

更新预期输出:

method    main_ingredient    cnt
================================
     1    2                  0
     1    3                  0
     1    5                  0
     1    6                  0
     2    2                  0
     2    3                  0
                .
                .
                .
                .
               etc

UPDATE 添加了 tbl_methodstbl_main_ingredients:

tbl_methods 的架构:

id    method_name
=================
1     Method 1
2     Method 2
      .
      .
      .
6     Method 6

tbl_main_ingredients 的架构:

id     ingredient_name
======================
1      Ingredient 1
2      Ingredient 2
       .
       .
       .
8      Ingredient 8

两个id都是他们table的主键,自增

您可能需要检查 main_ingredient 是否为空

SELECT method, ifnull(main_ingredient,0), COUNT(*) AS cnt FROM  `recipes` 
GROUP BY  method

交叉连接您的 2 个基表,然后在 recipes 上左连接。然后,如果您计算任何左连接的列,您将得到所需的结果:

select m.id, i.id, count(r.method) as cnt
  from tbl_methods m
 cross join tbl_main_ingredients i
  left join recipes r
    on r.method = m.id
   and r.main_ingredient = i.id
 group by m.id, i.id
 order by m.id, i.id

首先你需要在tbl_methodstbl_main_ingredients之间做一个CROSS JOIN table以获得所有可能的方法和成分组合。

稍后在上面的交叉连接 table 和你的 reipes table 之间进行左连接匹配 methodmain_ingredient.

因此,您将获得 methodmain_ingredient 所有可能组合的结果。如果 recipes table 中存在任何组合,那么您将获得相应的计数,否则您将获得 0 作为计数。

SELECT 
method_ingredients.method_id,
method_ingredients.ingredients_id,
COUNT(R.method) AS cnt
FROM 
(
    SELECT 
    TM.id AS method_id,
    TMI.id AS ingredients_id
    FROM tbl_methods TM
    CROSS JOIN tbl_main_ingredients TMI
) AS method_ingredients
LEFT JOIN `recipes` R ON R.method = method_ingredients.method_id AND R.main_ingredient = method_ingredients.ingredients_id
GROUP BY method_ingredients.method_id, method_ingredients.ingredients_id
ORDER BY method_ingredients.method_id, method_ingredients.ingredients_id;

您可以更喜欢此查询的较短版本:

SELECT 
 TM.id AS method_id,
 TMI.id AS ingredients_id,
 COUNT(R.method) AS cnt
FROM tbl_methods TM
CROSS JOIN tbl_main_ingredients TMI
LEFT JOIN `recipes` R ON R.method = TM.id AND R.main_ingredient = TMI.id
GROUP BY TM.id, TMI.id
ORDER BY TM.id, TMI.id;

更多:

关于COUNT的一些微妙之处:

SELECT COUNT(0);   Result: 1

SELECT COUNT(-1);  Result: 1

SELECT COUNT(NULL); Result: 0

SELECT COUNT(71); Result: 1

SQL FIDDLE

BTW 在您的用例中与 COALESCE 无关。 COALESCE returns 列表中的第一个 non-NULL 元素(如果有的话) NULL.

示例:

SELECT COALESCE(NULL,NULL,NULL,'abc',NULL,'def'); returns abc

SELECT COALESCE(NULL,NULL,NULL);  returns NULL