MySQL:按类别计数排序项目

时间:2015-02-05 01:12:13

标签: mysql sql-order-by

我目前使用以下完美运行的查询:

SELECT * FROM `items` WHERE `id` IN 
    (SELECT `item_id` FROM `categories_items` 
     WHERE `category_id` IN (1, 2) GROUP BY `item_id` 
     HAVING COUNT(`item_id`) = 2);

选择所有选定(复选框)类别中的所有项目。

问题在于,大多数商品属于多个类别,有些商品只有两个类别,当我只检查这两个商品时,我仍然会得到数百个商品的清单,这使得几乎无法找到几个类别。

我的第一个想法是在查询中的某处添加一个ORDER BY "number_of_total_categories_that_the_selected_item_is_in" ASC,但由于我甚至得到了当前的帮助,并且可能会有很多计算/子查询才能工作,我想到了items表格中的额外列,用于保存其所在类别的数量!

  • 是否可以向查询添加有效的ORDER BY子句,如果是,它会是什么样子?
  • 你还有其他想法吗?将"倒置"外键解决方案在这里工作?不是机会,对吗? :P

如果没有,我能想到的就是在需要的时候手动更新category_count中的items列。

编辑:Table field that holds row count from another table看起来很有趣,但我不知道它是否适用于MySQL。

1 个答案:

答案 0 :(得分:1)

您想使用join而不是in。以下查询筛选仅包含所需两个类别的项目。它还计算了可用于order by

的类别总数
SELECT i.*
FROM `items` i JOIN
       (SELECT `item_id`, COUNT(*) as cnt
        FROM `categories_items` 
        WHERE `category_id` IN (1, 2)
        GROUP BY `item_id` 
        HAVING COUNT(DISTINCT CASE WHEN category_id IN (1, 2) THEN category_id END) = 2
       ) c
       ON i.id = c.item_id
ORDER BY cnt ASC;

编辑:

如果您想计算所有类别,那么请删除where。它并没有真正做任何事情:

SELECT i.*
FROM `items` i JOIN
       (SELECT `item_id`, COUNT(*) as cnt
        FROM `categories_items` 
        GROUP BY `item_id` 
        HAVING COUNT(DISTINCT CASE WHEN category_id IN (1, 2) THEN category_id END) = 2
       ) c
       ON i.id = c.item_id
ORDER BY cnt ASC;