MySQL添加COUNT()值

时间:2014-08-08 14:27:02

标签: mysql sql

编辑: SQL Fiddle here

我正在研究产品Feed。我得到了一份优惠清单;

  • 每个优惠都有1个产品
  • 每件商品属于1类
  • 类别可以是另一个类别的子类别

我有三张桌子(我只会向你展示相关的行)

信息:

OFFERS
___________________
| id | product_id |
-------------------
|  1 |         16 |
-------------------
|  2 |         54 |
-------------------
|  3 |         52 |
-------------------
|  4 |         20 |
-------------------
|  5 |          7 |
-------------------
|  6 |          5 |
-------------------

产品:

PRODUCTS
_______________
| id | cat_id |
---------------
| 16 |      1 |
---------------
| 54 |      3 |
---------------
| 52 |      4 |
---------------
| 20 |      1 |
---------------
|  7 |     15 |
---------------
|  5 |      3 |
---------------

分类

CATEGORIES
_____________________________________________________________
| id | display_name | original_name | subcat_of | is_active |
-------------------------------------------------------------
|  1 | Cars         | automobiles   |         0 |         1 |
-------------------------------------------------------------
|  2 |              | motorcycles   |         0 |         0 |
-------------------------------------------------------------
|  3 | Muscle cars  | muscle-cars   |         1 |         1 |
-------------------------------------------------------------
|  4 | Hybrid cars  | treehugwagons |         1 |         1 |
-------------------------------------------------------------

我必须写两个查询。第一个需要

  • 返回名称并计算给定主要类别及其子类别的要约数量
  • 但仅限于该主要类别有效
  • 如果某个类别没有display_name,请使用original_name

我想我有这个:

SELECT
    offers.id AS offer_id,
    product_id,
    products.cat_id,
    CASE
        WHEN categories.display_name <> ''
        THEN categories.display_name
        ELSE categories.original_name
    END AS cat_name,
    COUNT(offers.id) as num_offers
FROM
    offers
INNER JOIN
    products
    ON
    product_id = products.id
INNER JOIN
    categories
    ON
    cat_id = categories.id
WHERE
    categories.is_active = 1
    AND
    (categories.id = :cat_id OR categories.subcat_of = :cat_id)
GROUP BY
    cat_name
ORDER BY
    cat_name ASC

我很确定这个查询远非理想,但就目前而言,它确实有效。

这是我需要的第二个问题,它给了我一些问题。那个人需要:

  • 返回名称并计算给定主要类别及其子类别的要约金额,并返回每个主要类别的总计数
  • 但仅限于该主要类别有效
  • 如果某个类别没有display_name,请使用original_name

我可以使用一些PHP自己进行求和,但如果在SQL中无法做到这一点,我会感到惊讶。

2 个答案:

答案 0 :(得分:1)

我相信这是可能而且相当简单,假设您没有子子类别:

  SELECT CASE 
           WHEN c_main.display_name <> ''
           THEN c_main.display_name
           ELSE c_main.original_name
         END cat_name,
         COUNT(o.id) as num_offers
    FROM offers o
    JOIN products p
      ON o.product_id = p.id
    JOIN categories c
      ON p.cat_id = c.id
     AND (c.id = :cat_id OR c.subcat_of = :cat_id)
  /* AND c.is_active = 1 /* Include if necessary */
    JOIN categories c_main
      ON c_main.id = :cat_id
     AND c_main.is_active = 1 
GROUP BY cat_name
ORDER BY cat_name ASC

我写的第一个查询是:

  SELECT CASE 
           WHEN c.display_name <> ''
           THEN c.display_name
           ELSE c.original_name
         END cat_name,
         COUNT(o.id) as num_offers
    FROM offers o
    JOIN products p
      ON o.product_id = p.id
    JOIN categories c
      ON p.cat_id = c.id
     AND (c.id = :cat_id OR c.subcat_of = :cat_id)
     AND c.is_active = 1
GROUP BY cat_name
ORDER BY cat_name ASC

暂且不说:

我还会考虑NULLdisplay_name s为空,然后你可以替换

CASE 
  WHEN c_main.display_name <> ''
  THEN c_main.display_name
  ELSE c_main.original_name
END cat_name

使用:

COALESCE(c_main.display_name, c_main.original_name) cat_name

答案 1 :(得分:0)

由于MySQL不支持递归查询,因此无法在MySQL中完成。你有三个选择:

  1. 使用some complex function模拟递归/分层查询。 (Related
  2. 切换到supports recursive queries using CTE
  3. 的SQL Server
  4. 写一点PHP。
  5. 由您决定:)

    作为旁注,我在这里留下了一篇由SO用户Models for Hierarchical data with SQL and PHP撰写的@Bill Karwin的有趣幻灯片,可能适合您的情况。