L R*_*ley 5 sql t-sql sql-server sql-server-2008 window-functions
寻找帮助,将其转换为SQL Server 2008友好版本,因为我无法解决。我尝试了交叉应用和内部联接(不是说我做对了)都无济于事...有什么建议吗?
这实际上是做一个库存表和一个订单表。并将两者结合起来,告诉我一旦库存被拿走该怎么办(有关更多详细信息,请参阅我之前的问题,更多详细信息)
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
Run Code Online (Sandbox Code Playgroud)
现在按分区划分的总和是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 |
+--------+--------+----------+---------+-----------+-------+---------+-----------------+
Run Code Online (Sandbox Code Playgroud)
一种直接的方法是使用 中的相关子查询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;
Run Code Online (Sandbox Code Playgroud)
哦,如果(PlaceB, Product, PickTime)不是唯一的,您将得到与原始查询有所不同的结果SUM() OVER。如果您需要完全相同的结果,则需要使用一些额外的列(例如ID)来解决关系。
| 归档时间: |
|
| 查看次数: |
1940 次 |
| 最近记录: |