MySQL计算联合表

时间:2017-07-13 13:55:17

标签: mysql join count left-join

我想计算行数,或者在这种情况下计算同一类别中的产品数量,如果该类别中没有产品,则返回零。

我的查询中的表格如下所示:

category                    category_lang                 media
------------                -------------                 ---------
category_id | published     category_id | name | alias    media_id | category_id
-----------------------     --------------------------    ----------------------
1            | 1            1           | One  | one      1        | 1
2            | 1            2           | Two  | two      2        | 2
3            | 1            3           | Three| three    3        | 3

media_lang                          product_category
-------------------------------     ----------------
media_id | url      | file_name     product_id | category_id
-------------------------------     ------------------------
1        | /images/ | file1.jpg     1          | 1
2        | /images/ | file2.jpg     2          | 1
3        | /images/ | file3.jpg     3          | 2

我希望得到这样的结果:

category_id | category_name | alias | media_id | url      | file_name | count
1           | One           | one   | 1        | /images/ | file1.jpg | 2
2           | Two           | two   | 2        | /images/ | file2.jpg | 1
3           | Three         | three | 3        | /images/ | file3.jpg | 0

我的查询目前看起来像这样

SELECT 
c.`category_id`, 
ca.`name`, 
ca.`alias`, 
m.`media_id`, 
ma.`url`, 
ma.`file_name`,
COUNT(p.`product_id`) AS `count`
FROM `category` c
LEFT JOIN `category_lang` ca ON (c.`category_id` = ca.`category_id`)
LEFT JOIN `media` m ON (c.`category_id` = m.`category_id`)
LEFT JOIN `media_lang` ma ON (m.`media_id` = ma.`media_id`)
LEFT JOIN `product_category` p ON (c.`category_id` = p.`category_id`)
WHERE c.`published` = 1
ORDER BY ca.`name`

我的逻辑显然是错误的,因为此查询将返回此信息:

category_id | category_name | alias | media_id | url      | file_name | count
1           | One           | one   | 1        | /images/ | file1.jpg | 3

如何达到预期效果?

2 个答案:

答案 0 :(得分:1)

我认为最简单(和理智)的方法是在一个单独的子查询中汇总product_category表中每个类别的产品计数,然后将其加入到您已有的产品中:

SELECT 
    c.category_id, 
    ca.name, 
    ca.alias, 
    m.media_id, 
    ma.url, 
    ma.file_name,
    COALESCE(t.cat_count, 0) AS cat_count
FROM category c
LEFT JOIN category_lang ca
    ON c.category_id = ca.category_id
LEFT JOIN media m
    ON c.category_id = m.category_id
LEFT JOIN media_lang ma
    ON m.media_id = ma.media_id
LEFT JOIN
(
    SELECT category_id, COUNT(*) AS cat_count
    FROM product_category
    GROUP BY category_id
) t
    ON c.category_id = t.category_id
WHERE c.published = 1
ORDER BY ca.name

请注意,您的product_category表没有任何没有产品的类别条目。这不是问题,因为在LEFT JOIN我们可以简单地将NULL计数视为零。如果给定类别与子查询中的任何内容不匹配,则会出现NULL值。

答案 1 :(得分:0)

在我看来,这是你在做计数的地方,你做的事情有计算的标准。添加额外条件,其中产品类别ID等于类别表中的类别ID应该修复不正确的计数。

SELECT 
c.`category_id`, 
ca.`name`, 
ca.`alias`, 
m.`media_id`, 
ma.`url`, 
ma.`file_name`,
COUNT(p.`product_id`) AS `count`
FROM `category` c
LEFT JOIN `category_lang` ca ON (c.`category_id` = ca.`category_id`)
LEFT JOIN `media` m ON (c.`category_id` = m.`category_id`)
LEFT JOIN `media_lang` ma ON (m.`media_id` = ma.`media_id`)
LEFT JOIN `product_category` p ON (c.`category_id` = p.`category_id`)
WHERE (c.`published` = 1) and (c.`category_id` = p.`category_id`)
ORDER BY ca.`name`