【问题标题】:count items and showing them as well计算项目并显示它们
【发布时间】:2014-06-17 19:22:48
【问题描述】:

我想编写一个查询,它返回一个包含我选择的项目的框列表,并按我选择的内容排序显示它们。如果我选择Item1,Item2和Item3,我希望看到的结果是:

BoxA, 3 , Item1
BoxA, 3 , Item2
BoxA, 3 , Item3
BoxB, 2 , Item2
BoxB, 2 , Item3

这意味着 BoxA 有 3 个我选择的项目,项目是 Item1,Item2,Item3。 我找不到进行单个查询的方法。我所能做的就是(请注意,为了简单起见,我使用 ids 而不是项目名称。添加项目名称很容易。):

 SELECT b.name,count(*) cnt, ib.i_id 
 FROM boxes b, items_boxes ib 
 WHERE b.id=ib.b_id and ib.i_id in (1,2,3,4) 
 GROUP BY b.id 
 ORDER BY cnt DESC;

此查询返回 Box 名称和其中项目的计数,而项目(或 i_id)只是第一个。 我如何获得我需要的东西?我应该使用两个选择吗?

sqlFiddle:example

【问题讨论】:

  • 请添加表格和一些数据。可能在sqlfiddle.com
  • 您能否发布您的查询返回的所需内容..

标签: mysql sql


【解决方案1】:

您需要将计数作为单独的子查询进行,并将其加入您的结果中。

SELECT
  b.name,
  ibc.cnt,
  ib.i_id
FROM
  boxes         b
INNER JOIN
  items_boxes   ib
    ON b.id = ib.b_id
INNER JOIN
(
  SELECT b_id, COUNT(*) cnt
    FROM items_boxes
   WHERE i_id IN (1,2,3,4)
GROUP BY b_id
)
  ibc
    ON b.id = ibc.b_id
WHERE
  ib.i_id IN (1,2,3,4)

要考虑没有物品的盒子,只需将INNER JOINs 转换为LEFT JOINs。

编辑:

添加了上述代码的 SQL Fiddle 示例。 SQL Fiddle 中的表名略有不同,因此已在此处修改 SQL 以反映这一点。

http://sqlfiddle.com/#!2/1d925/7

【讨论】:

  • 我想这是唯一的方法。是最优的吗?我有 400000 个盒子和 13000 个物品,但这些盒子最多应该有 20 个物品。
  • @mobinoob - 一如既往,这取决于。你会一直退回所有 400k 盒子,还是只退回一个子集?您会在另一个查询中使用结果,还是在可以在那里进行扫描和计数的应用程序中使用结果?其他 RDBMS 允许其他构造,例如 COUNT(ib.i_id) OVER (PARTITION BY ib.b_id) AS cnt,而不是使用子查询,但 MySQL 还不支持。如果这是您需要的,那就是您所需要的 - 您唯一的选择似乎是查看索引以优化查询,或者使用预先计算这些结果的另一个表。
猜你喜欢
  • 2018-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-13
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
相关资源
最近更新 更多