【问题标题】:Time summaries from multi-entity database来自多实体数据库的时间摘要
【发布时间】:2016-09-23 11:31:23
【问题描述】:

我有以下数据库架构(re image),

我正在尝试编写一个查询,它会返回类似这样的结果... (列标题):Product_Group - Product_Name - Week1 - Week2 - Week3 - Week4 - QTY_Order

Week1 是当前日期和前 7 天之间特定产品的所有销售额。 Week2 是 2 周前特定产品的所有销售额(因此在 currentdate -7 天和 currentdate -14 天之间)
Week3 是特定产品的所有销售额3 周前的产品...等;
QTY_Order 是第 1 周、第 2 周、第 3 周和第 4 周特定产品销售的平均值。

下面的 SQL 将产生:Product_Group - Product_Name - Week1 - QTY_Order(但 quantity_order 不正确)。

SELECT Product.ProductGroupId, Product.Name, SUM(SaleLine.Quantity) AS Week1, SUM(SaleLine.Quantity) AS OrderQty 
FROM Sale 
JOIN SaleLine ON Sale.ID = SaleLine.SaleId 
JOIN Product ON SaleLine.ProductId = Product.Id 
WHERE Sale.SaleDateTime > (CURDATE() - INTERVAL 7 DAY ) 
GROUP BY Product.ProductGroupId, Product.Name;

我还尝试了以下 SQL 来获取:Product_Name - Week1 - Week2 - QTY_Order(同样,qty_order 不正确),但 week2 返回所有空值。

SELECT Product.ProductGroupId, Product.Name, SUM(SaleLine.Quantity) AS Week1, (SELECT SUM(SaleLine.Quantity) 
    FROM SaleLine 
    JOIN Sale ON SaleLine.SaleID = Sale.ID 
    JOIN Product on SaleLine.ProductId = Product.Id 
    WHERE Sale.SaleDateTime BETWEEN (CURDATE() - INTERVAL 14 DAY) AND (CURDATE() - INTERVAL 7 DAY)) AS Week2, SUM(SaleLine.Quantity) AS QTY_TO_ORDER 
FROM Sale 
JOIN SaleLine ON Sale.ID = SaleLine.SaleId 
JOIN Product ON SaleLine.ProductId = Product.Id 
WHERE Sale.SaleDateTime > (CURDATE() - INTERVAL 7 DAY ) 
GROUP BY Product.ProductGroupId, Product.Name;

谁能指出我在第 2 周出现问题的地方(返回 Null)。
谁能想到任何更简单/更简洁的编码方式?
任何人都可以提供一些计算 QTY_Order 的指针吗?

提前感谢人们可以提供的任何帮助:-)

**编辑 - 由请求添加(不包括客户表):
创建表语句(还有各种作为约束的触发器不包括在内)

CREATE TABLE ProductGroup( Id int PRIMARY KEY AUTO_INCREMENT, Name varchar(50) NOT NULL );

CREATE TABLE Product( Id int PRIMARY KEY AUTO_INCREMENT, ProductGroupId int, Name varchar(100) NOT NULL, Price decimal(8,2), QuantityOnHand int NOT NULL, QuantitySold int NOT NULL, QuantityToOrder int NOT NULL, QuantityRequested int NOT NULL, CONSTRAINT FK_Product_ProductGroup FOREIGN KEY (ProductGroupId) REFERENCES ProductGroup(Id) );

CREATE TABLE Sale( Id int PRIMARY KEY AUTO_INCREMENT, CustomerId int, SaleDateTime datetime NOT NULL, CONSTRAINT Sale_Customer FOREIGN KEY (CustomerId) REFERENCES Customer(Id) );

CREATE TABLE SaleLine( Id int PRIMARY KEY AUTO_INCREMENT, ProductId int NOT NULL, SaleId int NOT NULL, Quantity int NOT NULL, CONSTRAINT FK_SaleLine_Product FOREIGN KEY (ProductId) REFERENCES Product(Id), CONSTRAINT FK_SaleLine_Sale FOREIGN KEY (SaleId) REFERENCES Sale(Id) );

【问题讨论】:

  • 虽然您的图表看起来确实很漂亮,但一些 show create table 语句和几行示例数据会更有用
  • 这称为数据透视表。以MySQL pivot table 为例。您必须将count 替换为sum。对于您的订单数量,您需要max(SaleLine.Quantity) AS OrderQty,因为您只需要一次。

标签: mysql


【解决方案1】:

您正在从您的信息中寻找五个摘要:Week1、Week2、Week3、Week4 和 QTY_Order。这会产生复杂的 GROUP BY 查询。

最好一步一步地处理这种事情。您的前两个步骤应该是编写生成正确 Week1 和 QTY_Order 查询的单独查询。这将帮助您正确处理业务逻辑。你想计算订单吗?您想汇总已售出的单位数吗?你想总结总收入吗?

(我不想尝试为您编写此类查询;这是您的数据,不是我的。)

一旦你做对了这样的事情,你就可以做一些类似这个伪代码的事情来获得你的每周总结。

  SELECT group, name,
         SUM( CASE WHEN saledate < CURDATE() - INTERVAL 0 DAY
                    AND saledate >= CURDATE() - INTERVAL 7 DAY THEN Quantity
                   ELSE 0 END) Week1,
         SUM( CASE WHEN saledate < CURDATE() - INTERVAL 7 DAY
                    AND saledate >= CURDATE() - INTERVAL 14 DAY THEN Quantity
                   ELSE 0 END) Week2,
         SUM( CASE WHEN saledate <  CURDATE() - INTERVAL 14 DAY
                    AND saledate >= CURDATE() - INTERVAL 21 DAY THEN Quantity
                   ELSE 0 END) Week3
    FROM (some subquery)
   GROUP BY group,name

诀窍是在 sum 函数中使用 case 语句来选择适当一周的交易。

这是一个查询的毛球。但它会起作用。

【讨论】:

    【解决方案2】:

    所以我已经让这段代码工作了:...

    SELECT Product.ProductGroupId, Product.Name, SUM(CASE WHEN Sale.SaleDateTime BETWEEN CURDATE() AND Sale.SaleDateTime <= (CURDATE() - INTERVAL 7 DAY) THEN SaleLine.Quantity ELSE 0 END) AS Week1, SUM(CASE WHEN Sale.SaleDateTime < (CURDATE() - INTERVAL 7 DAY) AND Sale.SaleDateTime >= (CURDATE() - INTERVAL 14 DAY) THEN SaleLine.Quantity ELSE 0 END) AS Week2, SUM(CASE WHEN Sale.SaleDateTime < (CURDATE() - INTERVAL 14 DAY) AND Sale.SaleDateTime >= (CURDATE() - INTERVAL 21 DAY) THEN SaleLine.Quantity ELSE 0 END) AS Week3, SUM(CASE WHEN Sale.SaleDateTime < (CURDATE() - INTERVAL 21 DAY) AND Sale.SaleDateTime >= (CURDATE() - INTERVAL 28 DAY) THEN SaleLine.Quantity ELSE 0 END) AS Week4
    FROM Sale JOIN SaleLine ON Sale.ID = SaleLine.SaleId JOIN Product ON SaleLine.ProductId = Product.Id GROUP BY Product.ProductGroupId, Product.Name;

    但我只是不确定如何做另一个案例陈述,以获得 Week1、Week2、Week3、Week4 之间的平均值

    有什么建议吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-31
      相关资源
      最近更新 更多