3

我有一个类似这样的mysql表:

销售日期产品 ID
----- ---------- ----
2013-04-20 09:00 美国广播公司 10
2013-04-20 09:00 DEF 15
2013-04-20 09:00 HIJ 15
2013-04-20 10:00 美国广播公司 5
2013-04-20 10:00 DEF 10
2013-04-20 10:00 HIJ 20
等等..

我想得到每个产品每小时销售量之间的差异,按降序排列,所以上面的结果是:

2013-04-20 10:00 HIJ 5
2013-04-20 10:00 ABC -5
2013-04-20 10:00 DEF -5

我已经尝试了一些事情,比如将表格与自身连接起来,但我无法做到正确。我该怎么做呢?

4

3 回答 3

1

您可以使用这样的查询:

SELECT t.date, t.productID, t.sold-tp.sold
FROM (
  SELECT t1.date, t1.productID, t1.sold, MAX(t2.date) date_prec
  FROM
    yourtable t1 INNER JOIN yourtable t2
    ON t1.productID=t2.productID AND t1.date>t2.date
  GROUP BY
    t1.date, t1.productID, t1.sold) t INNER JOIN yourtable tp
  ON t.productID=tp.productID and t.date_prec=tp.date

在此处查看小提琴。

在子查询中,我以相同的产品 ID 和条件将 yourtable 与自身连接起来t1.date>t2.date。按 t1.date、productID 和 sold 分组可以得到上一个日期时间,即MAX(t2.date). 然后,我再次将此子查询与 yourtable 加入,以获得sold前一天的值。

编辑

您可能还想使用这个:

SELECT t.date, t.productID, t.sold-tp.sold
FROM
  yourtable t INNER JOIN yourtable tp
  ON t.productID = tp.productID
     AND t.date = tp.date + INTERVAL 1 HOUR

在这里,我将返回前一小时sold之间的差异。sold

小提琴在这里

于 2013-05-10T22:41:12.653 回答
0

使用临时表很容易。首先通过以下方式总结您的数据:

CREATE TABLE sales_summary
(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    product_id CHAR(3) NOT NULL,
    date DATETIME NOT NULL,
    sold INT NOT NULL
)
SELECT
    NULL AS id,
    product_id,
    DATE_FORMAT(date, '%Y-%m-%d %H:00:00') date,
    SUM(sold) AS sold
FROM
    sales
GROUP BY
    product_id,
    DATE_FORMAT(date, '%Y-%m-%d %H:00:00')
ORDER BY
    1,2;

从该汇总表中,您可以创建报告:

SELECT
    b.product_id,
    a.date AS prev_hour,
    b.date AS this_hour,
    b.sold - a.sold AS diff_sold,
    a.sold AS prev_sold,
    b.sold AS this_sold
FROM
    sales_summary a
INNER JOIN
    sales_summary b ON b.id = a.id + 1 AND b.product_id = a.product_id 
ORDER BY
    a.product_id,
    a.date DESC;

返回:

+------------+---------------------+---------------------+-----------+-----------+-----------+
| product_id | prev_hour           | this_hour           | diff_sold | prev_sold | this_sold |
+------------+---------------------+---------------------+-----------+-----------+-----------+
| ABC        | 2013-04-20 10:00:00 | 2013-04-20 11:00:00 |        40 |        10 |        50 |
| ABC        | 2013-04-20 09:00:00 | 2013-04-20 10:00:00 |       -10 |        20 |        10 |
| DEF        | 2013-04-20 09:00:00 | 2013-04-20 10:00:00 |       -10 |        30 |        20 |
| HIJ        | 2013-04-20 09:00:00 | 2013-04-20 10:00:00 |        10 |        30 |        40 |
+------------+---------------------+---------------------+-----------+-----------+-----------+

一个工作示例位于http://sqlfiddle.com/#!2/897d9/1/0

于 2013-05-10T23:06:36.840 回答
0

这可以简单地使用相关子查询来完成,尽管它在大型表上可能效率不高:

select `date`, `productId`, ifnull(sold-(
  select sold
  from sales i
  where i.date < s.date
  and i.productId = s.productId
  limit 1
), sold) as diff
from sales s;

一个警告:该查询以及其他答案中的其他查询依赖于一件事:表中的数据已经按小时分组,在大多数情况下情况并非如此。

这是小提琴

于 2013-05-10T23:23:10.063 回答