繁体   English   中英

SQL 查询通过合并2个表来查找每天售出的书籍总数?

[英]SQL query to find the total number of books sold for each day by merging 2 tables?

我正在尝试查找每个product_idtxn_day的总销量(数量总和)。 我有 2 个表、 transactionscatalog ,如下所示:

表一: 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_idtitle_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM