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

Determine which POS sale takes precedence. Following logic tree in Sybase SQL Anywhere 10

我的小杂货店已与第三方合作接受在线订单。我做了一个 Excel sheet 来查询我们的产品数据库以获取大量产品信息,然后我将这些数据提供给另一个启用宏的工作 sheet 来完成繁重的工作并生成一个 .我每周上传的 CSV。

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

决定优先级的两个属性是"priority"和"date committed"。

因此,给定如下所示的数据:

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,运行ning SELECT @@VERSION 告诉我 12.0.1.3967

我对SQL Server 比较熟悉,但是Sybase 的SQL Anywhere 还是很相似的。

这是 "greatest N per group" 的问题。典型的解决方案(除 MySQL 之外的任何其他解决方案)是使用 ROW_NUMBER(),据我从 Sybase 在线书籍中得知,它可在 SQL Anywhere 10 及更高版本上使用。

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() (在这种情况下都可以)。这将允许 "ties" 出现。否则查询将是相同的。如果这种重复经常发生,那么您需要将第三列添加到 WINDOW 子句的 ORDER BY 部分。