SQL Server 2008版本的OVER(...行无界前置)

时间:2016-11-08 12:10:59

标签: sql sql-server sql-server-2008 tsql window-functions

寻求将此转换为SQL Server 2008友好的帮助,因为我无法解决这个问题。我试过交叉应用和内部联接(不是说我做对了)无济于事......有什么建议吗?

这基本上有一个库存表和一个订单表。 并将两者结合起来向我展示一旦股票被带走后要选择什么(有关详细信息,请参阅我之前的问题More Details

WITH ADVPICK
     AS (SELECT 'A'                  AS PlaceA,
                placeb,
                CASE
                  WHEN picktime = '00:00' THEN '07:00'
                  ELSE ISNULL(picktime, '12:00')
                END                  AS picktime,
                Cast(product AS INT) AS product,
                prd_description,
                -qty                 AS Qty
         FROM   t_pick_orders
         UNION ALL
         SELECT 'A'               AS PlaceA,
                placeb,
                '0',
                Cast(code AS INT) AS product,
                NULL,
                stock
         FROM   t_pick_stock),
     STOCK_POST_ORDER
     AS (SELECT *,
                Sum(qty)
                  OVER (
                    PARTITION BY placeb, product
                    ORDER BY picktime ROWS UNBOUNDED PRECEDING ) AS new_qty
         FROM   ADVPICK)
SELECT *,
       CASE
         WHEN new_qty > qty THEN new_qty
         ELSE qty
       END AS order_shortfall
FROM   STOCK_POST_ORDER
WHERE  new_qty < 0
ORDER  BY placeb,
          picktime,
          product  

现在按顺序分区的总和是SQL Server 2012+但是我有两台服务器在2008运行,因此需要转换...

预期结果:

+--------+--------+----------+---------+-----------+-------+---------+-----------------+
| PlaceA | PlaceB | Picktime | product | Prd_Descr |  qty  | new_qty | order_shortfall |
+--------+--------+----------+---------+-----------+-------+---------+-----------------+
| BW     | AMES   | 16:00    |    1356 | Product A | -1330 |     -17 |             -17 |
| BW     | AMES   | 16:00    |      17 | Product B |   -48 |     -42 |             -42 |
| BW     | AMES   | 17:00    |    1356 | Product A |  -840 |    -857 |            -840 |
| BW     | AMES   | 18:00    |    1356 | Product A |  -770 |   -1627 |            -770 |
| BW     | AMES   | 18:00    |      17 | Product B |  -528 |    -570 |            -528 |
| BW     | AMES   | 19:00    |    1356 | Product A |  -700 |   -2327 |            -700 |
| BW     | AMES   | 20:00    |    1356 | Product A |  -910 |   -3237 |            -910 |
| BW     | AMES   | 20:00    |    8009 | Product C |  -192 |     -52 |             -52 |
| BW     | AMES   | 20:00    |     897 | Product D |   -90 |     -10 |             -10 |
+--------+--------+----------+---------+-----------+-------+---------+-----------------+

1 个答案:

答案 0 :(得分:4)

一种直截了当的方法是在CROSS APPLY中使用相关的子查询。

如果你的桌子或多或少,那么你的下一个问题就是如何让它变快。 PlaceB, Product, PickTime INCLUDE (Qty)上的索引应该有所帮助。但是,如果你的表格非常大,那么光标会更好。

WITH
ADVPICK
AS
(
    SELECT 'A' as PlaceA,PlaceB, case when PickTime = '00:00' then '07:00' else isnull(picktime,'12:00') end as picktime, cast(Product as int) as product, Prd_Description, -Qty AS Qty FROM t_pick_orders
    UNION ALL
    SELECT 'A' as PlaceA,PlaceB, '0', cast(Code as int) as product, NULL, Stock FROM t_pick_stock
)
,stock_post_order
AS
(
    SELECT
        *
    FROM
        ADVPICK AS Main
        CROSS APPLY
        (
            SELECT SUM(Sub.Qty) AS new_qty
            FROM ADVPICK AS Sub
            WHERE
                Sub.PlaceB = Main.PlaceB
                AND Sub.Product = Main.Product
                AND T.PickTime <= Main.PickTime
        ) AS A
)
SELECT
    *,
    CASE WHEN new_qty > qty THEN new_qty ELSE qty END AS order_shortfall
FROM
    stock_post_order
WHERE
    new_qty < 0
ORDER BY PlaceB, picktime, product;

哦,如果(PlaceB, Product, PickTime)不是唯一的,那么使用SUM() OVER的原始查询会得到一些不同的结果。如果您需要完全相同的结果,则需要使用一些额外的列(例如ID)来解决关系。