确定哪个POS销售优先。遵循Sybase SQL Anywhere 10中的逻辑树

时间:2016-07-03 21:53:11

标签: sql sybase sqlanywhere

我的小杂货店与第三方合作接受网上订单。我制作了一个Excel表格,用于查询我们的产品数据库以获取大量产品信息,然后我将这些数据提供给另一个支持宏的工作表,该工作表可以完成繁重工作并生成我每周上传的.CSV。

我现在要做的是提取当前和未来的销售信息,以便我们可以做广告。通过将它们放入称为“工作表”的分组中,在我们的POS中创建销售。复杂因素是产品可以同时存在于多个工作表中,并且有一个逻辑树可以确定哪个工作表会在任何​​给定时间影响扫描价格。

确定优先级的两个属性是“priority”和“date committed”。

  • 三个优先级,高,中和低分别表示为1,2和3。优先级较高的工作表将始终覆盖较低优先级的工作表。
  • 当工作表具有相同的优先级时,最近提交的那个优先。

所以,给定的数据如下:

item_id        worksheet_name   priority   date_committed            sale_start_date           sale_end_date             sale_price
011259904209   A                2          2016-06-22 09:21:09.041   2016-06-29 00:00:00.000   2016-07-20 11:00:00.000   2.0000
074682105322   B                2          2016-06-22 09:49:31.722   2016-07-20 00:00:00.000   2016-08-03 11:00:00.000   2.0000
074682105322   C                2          2016-06-22 08:57:04.641   2016-07-19 00:00:00.000   2016-08-03 16:00:00.000   2.0000
042563013660   A                2          2016-06-22 09:21:09.048   2016-06-29 00:00:00.000   2016-07-20 11:00:00.000   3.9900
042563013660   D                1          2016-06-25 14:03:33.499   2016-06-29 00:00:00.000   2016-07-05 23:59:59.000   2.9900
042563013660   E                2          2016-06-22 08:49:13.515   2016-06-28 00:00:00.000   2016-07-20 16:00:00.000   3.9900
073360772054   A                2          2016-06-22 09:21:09.114   2016-06-29 00:00:00.000   2016-07-20 11:00:00.000   3.9900
073360772054   B                2          2016-06-22 09:49:31.831   2016-07-20 00:00:00.000   2016-08-03 11:00:00.000   3.9900
073360772054   E                2          2016-06-22 08:49:13.520   2016-06-28 00:00:00.000   2016-07-20 16:00:00.000   3.9900
073360772054   C                2          2016-06-22 08:57:04.649   2016-07-19 00:00:00.000   2016-08-03 16:00:00.000   3.9900
012993221010   A                2          2016-06-22 09:21:09.110   2016-06-29 00:00:00.000   2016-07-20 11:00:00.000   3.3900
012993221010   B                2          2016-06-22 09:49:31.828   2016-07-20 00:00:00.000   2016-08-03 11:00:00.000   3.3900
012993221010   D                1          2016-06-25 14:03:33.502   2016-06-29 00:00:00.000   2016-07-05 23:59:59.000   2.9900
012993221010   E                2          2016-06-22 08:49:13.517   2016-06-28 00:00:00.000   2016-07-20 16:00:00.000   3.3900
012993221010   C                2          2016-06-22 08:57:04.646   2016-07-19 00:00:00.000   2016-08-03 16:00:00.000   3.3900

我想得到这个:

Run on 6/27             
item_id        worksheet_name   sale_start_date           sale_end_date             sale_price
011259904209   A                2016-06-29 00:00:00.000   2016-07-20 11:00:00.000   2.0000
074682105322   C                2016-07-19 00:00:00.000   2016-07-20 00:00:00.000   2.0000
042563013660   E                2016-06-28 00:00:00.000   2016-06-29 00:00:00.000   3.9900
073360772054   E                2016-06-28 00:00:00.000   2016-06-29 00:00:00.000   3.9900
012993221010   E                2016-06-28 00:00:00.000   2016-06-29 00:00:00.000   3.9900


Run on 6/29             
item_id        worksheet_name   sale_start_date           sale_end_date             sale_price
011259904209   A                2016-06-29 00:00:00.000   2016-07-20 11:00:00.000   2.0000
074682105322   C                2016-07-19 00:00:00.000   2016-07-20 00:00:00.000   2.0000
042563013660   D                2016-06-29 00:00:00.000   2016-07-05 23:59:59.000   2.9900
073360772054   A                2016-06-29 00:00:00.000   2016-07-19 00:00:00.000   3.9900
012993221010   D                2016-06-29 00:00:00.000   2016-07-05 23:59:59.000   2.9900

将重叠销售期结合起来以反映购物者的看法的奖励积分,但这不是必需的。

如何使用SQL获得此结果?我们的销售周三到周二,在完成每周价格变动后,我理想地在周三下午或周四早上生成下周的数据文件。

我们有数以万计的产品存档。

Here's a graphical representation of the worksheet priorities per day

这适用于SQL Anywhere 10,运行SELECT @@VERSION告诉我 12.0.1.3967

1 个答案:

答案 0 :(得分:0)

我最熟悉SQL Server,但Sybase的SQL Anywhere仍然非常相似。

这是每组最大的N"问题。典型的解决方案(在MySQL之外的任何其他方法)是使用ROW_NUMBER(),这在SQL Anywhere 10及更高版本中可用,据我在Sybase书籍中可以看出。

SELECT a.item_id,
    a.worksheet_name,
    a.sale_start_date,
    a.sale_end_date,
    a.sale_price
FROM (
    SELECT item_id,
        worksheet_name,
        sale_start_date,
        sale_end_date,
        sale_price,
        ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY priority, date_committed DESC) AS rn
    FROM UnnamedSalesTable
    WHERE sale_start_date <= CURRENT DATE
        AND sale_end_date > CURRENT DATE) a
WHERE a.rn = 1

显然,您可以将CURRENT DATE替换为您想要运行的任何日期值。

如果您碰巧有两个相同的prioritydate_committed的销售,那么您仍然只能获得一行。换句话说,如果有重复,你就不会知道。我怀疑你想要的是什么。但是,如果您需要查看重复项,那么您需要使用RANK()或DENSE_RANK()来代替ROW_NUMBER()(在这种情况下可以工作)。这将允许&#34; tie&#34;现身。否则查询将是相同的。如果这种重复发生很多,那么您将要在WINDOW子句的ORDER BY部分添加第三列。