[英]SQL query to find the total number of books sold for each day by merging 2 tables?
我正在尝试查找每个product_id
和txn_day
的总销量(数量总和)。 我有 2 个表、 transactions
和catalog
,如下所示:
表一: transaction
market_id, txn_day, customer_id, product_id, quantity
1,2019-03-01,1,B0002,1
1,2019-03-01,2,B0003,1
1,2019-03-01,1,B0001,1
3,2019-03-01,3,B0001,1
3,2019-03-01,4,B0002,1
4,2019-03-01,1,B0002,1
4,2019-03-01,5,B0001,1
4,2019-03-01,6,B0001,1
表 2: catalog
market_id, product_id, title_name
1,B0001, Harry Potter 1
1,B0002, Harry Potter 2
1,B0003, Harry Potter 3
3,B0001, Harry Potter 1
3,B0002, Harry Potter 2
3,B0003, Harry Potter 3
4,B0001, Harry Potter 1
4,B0002, Harry Potter 2
4,B0003, Harry Potter 3
我编写了以下查询并获得了product_id
的总销量(数量总和):
SELECT
transaction.txn_day, transaction.product_id,
SUM(quantity) AS quantity
FROM
transaction
GROUP BY
transaction.product_id, transaction.txn_day;
我尝试以下查询来获取每个product_id
的title_name
,但它似乎不正确。
SELECT
transaction.txn_day, transaction.product_id, catalog.title_name,
SUM(quantity) AS quantity
FROM
catalog
INNER JOIN
transaction ON catalog.product_id = transaction.product_id
GROUP BY
transaction.txn_day, transaction.product_id, catalog.title_name;
我得到以下结果:
|txn_day |product_id |title_name |quantity
|2019-03-01 |B0002 |Harry Potter 2 |9
|2019-03-01 |B0001 |Harry Potter 1 |12
|2019-03-01 |B0003 |Harry Potter 3 |3
我期望结果是这样的:
|txn_day | product_id | quantity | title_name
|2019-03-01 | B0003 | 1 | Harry Potter 3
|2019-03-01 | B0002 | 3 | Harry Potter 2
|2019-03-01 | B0001 | 4 | Harry Potter 1
请提出查询所需的任何更改。
我加载了您的数据并得到以下结果:
DATE ID TITLE QTY
3/1/2019 B0002 Harry Potter 2 9
3/1/2019 B0003 Harry Potter 3 3
3/1/2019 B0001 Harry Potter 1 12
您在这里关于错误的线索是,您的数量对于每条记录来说都是 3 倍。
如果您查看您的 INNER JOIN,您只是通过 product_id 加入。
查看您的交易行。
您可以看到每个 product_id 与 3 个不同的 market_id 一起存在,这就是您的数量增加三倍的原因。
解决方案:将 market_id 添加到 JOIN 中:
SELECT t.txn_day
,t.product_id
,c.title_name
,SUM(quantity) AS quantity
FROM catalog c
INNER JOIN transactions t ON c.product_id = t.product_id AND c.market_id = t.market_id
GROUP BY t.txn_day, t.product_id, c.title_name
order by c.title_name;
你会得到你的结果:
3/1/2019 B0001 Harry Potter 1 4
3/1/2019 B0002 Harry Potter 2 3
3/1/2019 B0003 Harry Potter 3 1
这是错误的,因为 product_id 和 title_name 在目录中不是唯一的。 考虑:
SELECT transaction.txn_day, transaction.product_id, title_name,
sum(quantity) as qty FROM (SELECT DISTINCT product_id, title_name FROM catalog) AS cat
INNER JOIN transaction ON cat.product_id=transaction.product_id
group by transaction.txn_day, transaction.product_id, catalog.title_name;
此外,与本机字段名称相同的字段别名可能会在某些系统中导致问题,它在 Access 中会出现。
我认为你需要加入两个专栏,而不是一个——市场和产品:
SELECT t.txn_day, product_id, c.title_name, SUM(quantity) as quantity
FROM catalog c INNER JOIN
transaction t
USING (product_id, market_id)
GROUP BY t.txn_day, product_id, c.title_name;
这使用USING
子句来简化JOIN
条件。 它还引入了表别名,因此查询更易于编写和阅读。
您的数据表明product_id
单独是title_name
的关键。 所以:
SELECT t.*, c.title_name
FROM (
SELECT txn_day, product_id, sum(quantity) AS sum_quantity
FROM transaction
GROUP BY txn_day, product_id
) t
LEFT JOIN (
SELECT DISTINCT product_id, title_name
FROM catalog
) c USING (product_id);
你真的应该有一个表格product
列出不同的产品。
(除非您的样本数据具有误导性,并且只有组合(market_id, product_id)
是唯一的 - 在这种情况下,在聚合中省略market_id
是没有意义的。因此我回到我的第一个假设。)
除此之外,我使用子查询SELECT DISTINCT product_id, title_name FROM catalog
即时派生该表。
如果在表catalog
中找不到product_id
,则LEFT JOIN
而不是JOIN
是一种消除行的保险。
此外,先聚合然后再加入通常更便宜。 看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.