MySQL COUNTs的一对多和

时间:2014-12-21 12:47:06

标签: mysql join count one-to-many

经过2天的搜索和尝试类似的问题,我已经到了需要提问的地步!

我有以下数据库结构(简化)..

mt_product           | mt_sku                              | mt_price
==========           | ======                              | ========
id | brand_id | mpn  | id | product_id | retailer_id | sku | id | sku_id | price | date

例如......
*一罐可口可乐是一种产品。
*它可以在许多不同的零售商处出售,他们都将拥有SKU *此SKU将有一个价格,可以每天更改。

我想列出产品的总价格 为了列出这个,我目前有以下查询几乎可以工作......

SELECT
p.id AS pid, p.title AS p_title, p.cat, p.mpn,
b.id AS bid, b.name AS brand,
(SELECT COUNT(s.id) FROM mt_sku AS s WHERE s.pid = p.id) AS num_sku,
(SELECT COUNT(gbp.id) FROM mt_price AS gbp INNER JOIN mt_sku ON mt_sku.id = gbp.sid ) AS num_price
FROM mt_product AS p
INNER JOIN mt_brand b ON p.bid = b.id
INNER JOIN mt_sku s ON p.id = s.pid

num_sku按预期返回,但是当我为num_price引入第二个子查询时(我已多次修改)我要么...... *没有pid的重复,但num_price是SKU的价格总数,而不是此product_id的价格数量(如上所述)eg1_img *正确的num_price数,但不是总计num_price总数,pid在表中重复(如下面的查询) - 因此,当pid重复时,这不会给我我想要的结果。我添加了DISTINCT,因为它帮助了早期版本的查询,它现在没有任何区别。 eg2_img

SELECT
DISTINCT(p.id) AS pid, p.title AS p_title, p.cat, p.mpn,
b.id AS bid, b.name AS brand,
(SELECT COUNT(s.id) FROM mt_sku AS s WHERE s.pid = p.id) AS num_sku,
(SELECT COUNT(gbp.id) FROM mt_price AS gbp WHERE s.id = gbp.sid) AS num_price
FROM mt_product AS p
INNER JOIN mt_brand b ON p.bid = b.id
INNER JOIN mt_sku s ON p.id = s.pid

我很确定关键是这个 产品可以有多个SKU,其中SKU有多个价格历史记录
架构的任何帮助或想法都是一流的。

2 个答案:

答案 0 :(得分:0)

如果您想列出总价格,那么您需要相关性。

您的第一次计数没问题,因为它与外部查询相关。第二个没有相关性,所以这看起来很奇怪。以下修复了num_price子查询:

SELECT p.id AS pid, p.title AS p_title, p.cat, p.mpn,
       b.id AS bid, b.name AS brand,
       (SELECT COUNT(s2.id) FROM mt_sku s2 WHERE s2.pid = p.id) AS num_sku,
       (SELECT COUNT(gbp.id) FROM mt_price gbp WHERE s.id = gbp.sid ) AS num_price
FROM mt_product p INNER JOIN
     mt_brand b
     ON p.bid = b.id INNER JOIN
     mt_sku s
     ON p.id = s.pid;

我也不确定为什么你在外部查询中有所有连接。我假设给定的产品将有多行,并且您希望多行具有相同的num_skunum_price值。

答案 1 :(得分:0)

试试这个:

SELECT
  p.id AS pid, p.title AS p_title, p.cat, p.mpn,
  b.id AS bid, b.name AS brand,
  COUNT(DISTINCT s.id) AS num_sku,
  COUNT(gbp.id) AS num_price
FROM mt_product AS p
  INNER JOIN mt_brand b ON p.brand_id = b.id
  INNER JOIN mt_sku s ON p.id = s.product_id
  INNER JOIN mt_price gbp ON s.id = gbp.sku_id
GROUP BY b.id, p.id

未定义SKU的产品不会出现在结果集中。使用LEFT JOIN mt_sku使其显示在结果集中(0num_sku num_price}:

  LEFT JOIN mt_sku s ON p.id = s.product_id

在查询的两个变体中,未定义价格的产品将不会出现在结果集中。使用LEFT JOIN mt_price将其包含在结果集中(0num_price):

  LEFT JOIN mt_price gbp ON s.id = gbp.sku_id

查看JOINsGROUP BYGROUP BY aggregate functions的MySQL文档。