根据时间间隔使用MAX(价格)或MAX(日期)分组BY产品

时间:2013-01-15 14:10:21

标签: mysql date group-by max min

我一直在寻找2天的答案,但仍然没有。求你帮帮我。

我有一个数据库,其中包含产品,产品价格以及注册价格的日期:

product_id | price | date
-------------------------
    1      | 8.95  | 2012-12-01
    2      | 3.40  | 2012-12-01
    1      | 9.05  | 2012-12-19
    3      | 2.34  | 2012-12-24
    3      | 2.15  | 2012-12-01
    1      | 8.80  | 2012-12-19
    1      | 8.99  | 2012-12-02
    2      | 3.45  | 2012-12-02

观察可能在同一天(第3行和第6行)为产品设置不同的价格值。这是因为单个产品有很多供应商。数据库上也有一个供应商专栏,但我发现它与解决方案无关。如果我错了,你可以将它添加到解决方案中。

基本上我想要的是编写一个返回两个组合数据集的查询,如下所示:

  • 首先是上个月插入的产品的最低价格。由于今天是1月15日,查询应该读取第3,4和6行,应用最低价格,并且仅返回第4行和第6行,两者都是上个月该产品的最低价格。
  • 第二套是由最后插入的产品制作的,上个月没有注册价格。即,对于第一组中未显示的产品,查询应搜索最后插入的产品。

我希望这很清楚。如果不是,请向我询问。

此数据库的查询结果应为:

product_id | price | date
-------------------------
    1      | 8.80  | 2012-12-19 <-Min price for product 1 on last month
    3      | 2.34  | 2012-12-24 <-Min price for product 3 on last month
    2      | 3.45  | 2012-12-02 <-No reg for product 2 on last month, show last reg.

我已经尝试了一切:UNION,(DATE_SUB(CURDATE(),INTERVAL 1个月),MIN(价格),MAX(日期)等等。没有任何作用。我现在不知道在哪里搜索帮助我。

4 个答案:

答案 0 :(得分:1)

(SELECT product_id, MIN(price), date
FROM products
WHERE date + INTERVAL 1 MONTH > NOW()
GROUP BY product_id)
UNION
(SELECT product_id, price, MAX(date)
FROM products
WHERE product_id NOT IN (SELECT product_id
    FROM products
    WHERE date + INTERVAL 1 MONTH > NOW()
    GROUP BY product_id)
GROUP BY product_id)

这应该可行,但我不确定这是最优化的方法。

答案 1 :(得分:0)

将其分解为几个子查询:

  • 产品价格在上个月,最低价格
    • 加入该价格的日期

UNION

  • 上个月没有价格的产品,最长日期
    • 加入该日期的价格

SQL小提琴

Here

查询

SELECT MINPRICE.product_id, P.date, MINPRICE.price
    FROM
    (
        -- Min price in last 31 days
        SELECT product_id, MIN(price) AS price
            FROM Prices
            WHERE DATEDIFF(CURDATE(), date) < 31
            GROUP BY product_id
    ) MINPRICE
    -- Join in to get the date that the price occured on
    INNER JOIN Prices P ON
        P.product_id = MINPRICE.product_id
        AND
        P.price = MINPRICE.price
UNION
SELECT MAXDATE.product_id, MAXDATE.date, P.price
    FROM
    (
        -- Product with no price in last 31 days - get most recent date
        SELECT product_id, MAX(date) AS date
            FROM Prices
            WHERE product_id NOT IN
            (
                SELECT product_id
                    FROM Prices
                    WHERE DATEDIFF(CURDATE(), date) < 31
            )
    ) MAXDATE
    -- join in price on that date
    INNER JOIN Prices P ON
        P.product_id = MAXDATE.product_id
        AND
        P.date = MAXDATE.date

答案 2 :(得分:0)

这样的事情会起到作用:

SELECT * FROM ( 
    SELECT DISTINCT b.product_id, IF (c.min IS NULL,(SELECT ROUND(e.price,2) FROM products AS e WHERE e.product_id = b.product_id ORDER BY e.date DESC LIMIT 1 ),c.min) AS min, IF (c.date IS NULL,(SELECT f.date FROM products AS f WHERE f.product_id = b.product_id ORDER BY f.date DESC LIMIT 1 ),c.date) AS date, IF(c.min IS NULL,'<-No reg for product 2 on last month, show last reg.','<-Min price for product 1 on last month') as text FROM products AS b
    LEFT JOIN
        (SELECT a.product_id, round(MIN(a.price),2) AS min, a.date FROM products AS a WHERE a.date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 MONTH) AND CURDATE() GROUP BY a.product_id) AS c 
        ON (b.product_id = c.product_id)
    ) AS d
    ORDER BY d.text, d.product_id

提供输出:

product_id|min|date|text
1|8.80|2012-12-19|<-Min price for product 1 on last month
3|2.34|2012-12-24|<-Min price for product 1 on last month
2|3.45|2012-12-02|<-No reg for product 2 on last month, show last reg.

答案 3 :(得分:-1)

不是我测试过但你可以试试......

SELECT * FROM 
  (SELECT * FROM (
      SELECT * FROM table ORDER BY date DESC)
  as tmp GROUP BY product_id) t1
LEFT JOIN
  (SELECT * FROM (
      SELECT * FROM table WHERE date => CURDATE() ORDER BY price)
  as tmp2 GROUP BY product_id) t2
ON t1.product_id = t2.product_id