【问题标题】:SELECT count of grouped Products AND the cheapest price for each product WHERE not yet filled选择分组产品的数量和尚未填写的每个产品的最便宜价格
【发布时间】:2022-09-30 07:14:21
【问题描述】:

我试图选择不同的产品,按除 ID 之外的所有列分组,以及该类型产品的最便宜的出价。有时,该产品可能没有出价,所以我需要离开加入来解决这些问题。

我将在下面添加所需的输出以及一种伪查询来帮助解释。

如果有帮助,您可以想象一个产品搜索页面。当用户搜索时,它将所有相同的产品组合在一起。这些产品可以由许多不同的卖家出售,但我们只想在结果中显示一次,以及搜索时该产品的最便宜价格。

重要提示:可以取消“有效”出价,这会覆盖该行的状态。但是,由于该系统的工作方式,如果投标被接受(填写),它会为该 ProductID 创建一个新的投标行。所以,我需要最便宜的出价仍然活跃并且基于TimeOfBid 字段,之后没有“已填充”出价。

状态

  1. 已取消 - 将 BidID 从活动更新为已取消(覆盖)
  2. 有效 - 有效出价
  3. 已填充 - 这是一个新行。如果它是 最新行,这意味着不再有任何有效的出价。

    我要返回的数据

    SELECT count(Name), Size, Weight, Color, BidID, Status, min(Price)
    -- WHERE the bid is still active (has \'Active\' status and no \'Filled\' bid with later time) --
    -- AND is the cheapest price
    -- group by Size, Weight, Color, BidID, Status
    

    还需要 WHERE 子句,这些子句基于最终用户使用的过滤器构建。例子:

    WHERE Status = \'Active\' and Weight = \'1kg\'
    WHERE Status = \'Active\'
    WHERE Size = \'1m\' and Weight in (\'1kg\', \'2kg\')
    

    产品表

    | ProductID (PK) | Name        | Size | Weight | Color  |
    | --------       | --------    | -----| -----  | -----  | 
    | 1              | Black Table | 1m   | 2kg    | Black  | 
    | 2              | Purple Table| 1m   | 3kg    | Purple | 
    | 3              | Small Table | 1m   | 3kg    | Black  | 
    | 4              | Small Table | 1m   | 3kg    | Black  | 
    | 5              | Black Table | 1m   | 2kg    | Black  | 
    | 6              | Purple Table| 1m   | 3kg    | Purple |
    | 7              | Small Table | 1m   | 3kg    | Black  | 
    | 8              | Small Table | 1m   | 3kg    | Black  | 
    | 9              | Big Table   | 2m   | 4kg    | Gray   |
    

    投标表

    | BidID (PK)     | ProductID   | Status      | Price   | TimeOfBid           |
    | --------       | -------     | --------    | -----   | ------------------- |
    | 1              |  1          | Filled      | 123.5   | 2022-09-20 02:51:41 | <= ID 1 now has no active bid
    | 2              |  2          | Cancelled   | 325.99  | 2022-09-20 02:50:28 |
    | 3              |  1          | Active      | 85.99   | 2022-09-20 01:16:24 | 
    | 4              |  3          | Cancelled   | 315.99  | 2022-09-20 01:15:58 |
    | 5              |  4          | Active      | 113.5   | 2022-09-20 01:15:39 | <= Cheapest for ID 4
    | 6              |  3          | Cancelled   | 305.99  | 2022-09-20 01:15:12 |
    | 7              |  1          | Active      | 82.99   | 2022-09-20 01:14:46 | 
    | 8              |  2          | Active      | 345.99  | 2022-09-20 01:13:33 | <= Cheapest for ID 2
    

    期望的输出示例

    | Count          | Name        | Size | Weight | Color  | BidID | CheapestPrice |
    | --------       | --------    | -----| -----  | -----  | ----- | -----        |
    | 38             | Black Table | 1m   | 2kg    | Black  |  1    | 123.5
    | 21             | Purple Table| 1m   | 3kg    | Purple |  2    | 89.95
    | 13             | Small Table | 1m   | 3kg    | Black  |  3    | 65.94
    | 6              | Big Table   | 2m   | 4kg    | Gray   |  NULL | NULL
    

    昨天有人通过以下查询帮助我接近(我未能给出完整的图片)。它只是没有考虑到出价被新的出价行覆盖,状态设置为“已填充”。它也不会返回分组产品的 count()。

    WITH CTE AS
    (SELECT P.PRODUCTID PPID,NAME,SIZE,WEIGHT,COLOR
           ,B.BIDID,B.PRODUCTID AS BPID,STATUS,PRICE
             ,ROW_NUMBER() OVER (PARTITION BY NAME,SIZE,WEIGHT,COLOR ORDER BY PRICE) RN
    FROM PRDUCTS P
    JOIN BIDS B ON B.PRODUCTID = P.PRODUCTID
    ) 
    SELECT PPID,NAME,SIZE,WEIGHT,COLOR,PRICE FROM CTE 
    WHERE  RN = 1
    UNION ALL
    SELECT DISTINCT PRODUCTID,NAME,SIZE,WEIGHT,COLOR,NULL
    FROM   PRDUCTS P
    WHERE  NOT EXISTS
            (SELECT 1 FROM CTE WHERE CTE.NAME = P.NAME      AND
                                             CTE.WEIGHT = P.WEIGHT  AND
                                             CTE.COLOR = P.COLOR);
    
  • 您所需的输出与您的示例数据不匹配,BID\'s 不包含例如输出中的 ProductID 为 9。请使用您提供的示例数据更新您想要的输出。此外,您想要的输出中的第一行显示价格为 123.5,它映射到 ProductID 1,BidID 1 - 已填充,您声明您只想要 ACTIVE。

标签: mysql


【解决方案1】:

整个查询:

SELECT
    Count( p.ProductID ) AS Count,
    p.`Name`,
    p.Size,
    p.Weight,
    p.Color,
    b.BidID,
    b.Price 
FROM
    products AS p
    LEFT JOIN (
SELECT
    MIN( bi.Price ) AS Price,
    bi.BidID AS BidID,
    bi.ProductID AS ProductID 
FROM
    bids AS bi
    JOIN (
SELECT
    bc.TimeOfBid AS bids_last_filled 
FROM
    bids AS bc 
WHERE
    bc.ProductID = ProductID 
    AND bc.`Status` = 'Filled' 
ORDER BY
    bc.TimeOfBid DESC 
    LIMIT 1 
    ) BLF 
WHERE
    bi.`Status` = 'Active' 
    AND bi.TimeOfBid > BLF.bids_last_filled 
GROUP BY
    bi.ProductID 
    ) b ON p.ProductID = b.ProductID 
GROUP BY
    p.`Name`

查询说明:https://prnt.sc/QloA5UuQRqcQ

查询结果: https://prnt.sc/uyOnjGayvGfy

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 2017-12-05
    • 2015-11-05
    • 1970-01-01
    相关资源
    最近更新 更多