我一直在尝试从不同的表中获取查询的最简单方法,但只根据另一个表显示数量
- 我想创建一个Pickroute报告 - 挑选路线将有一个idorder,文章,数量和位置
- 如果我的订单需要25 ITEM01 - 我将从LOC01拿10分,从LOC02拿15分 - 所有的locatios都有一个序列 - 完成25后,我需要更新SPLITTABLE中的IDORDER列
让我解释一下
我有以下表格
SALESORDER 表格:
IDORDER ARTICLE QUANTITY
----------------------------
1 ITEM01 25
1 ITEM02 10
2 ITEM01 20
3 ITEM01 5
3 ITEM03 4
库存表:
ARTICLE QUANTITY LOCATION SEQUENCE
---------------------------------------
ITEM01 10 LOC01 1
ITEM01 30 LOC02 2
ITEM01 30 LOC03 3
ITEM02 2 LOC02 2
ITEM02 10 LOC03 3
ITEM03 1 LOC01 1
ITEM03 5 LOC02 2
我想要得到的是以下
OPORDER 表格:
ARTICLE QUANTITY LOCATION IDORDER
----------------------------------------
ITEM01 10 LOC01 1
ITEM01 15 LOC02 1
ITEM02 2 LOC02 1
ITEM02 8 LOC03 1
ITEM01 15 LOC02 2
ITEM01 5 LOC03 2
ITEM01 5 LOC03 3
ITEM03 1 LOC01 3
ITEM03 4 LOC02 3
现在让我告诉你我为完成它所做的工作(至少尝试这样做)。
模式:
SALESORDER
DROP TABLE IF EXISTS SALESORDER
CREATE TABLE SALESORDER
(
IDORDER INT,
ARTICLE VARCHAR(50),
QUANTITY INT
);
INSERT SALESORDER (IDORDER, ARTICLE, QUANTITY)
VALUES (1, 'ITEM01', 25), (1, 'ITEM02', 10),
(2, 'ITEM01', 20), (3, 'ITEM01', 5),
(3, 'ITEM03', 4)
广告
DROP TABLE IF EXISTS INVENTORY
CREATE TABLE INVENTORY
(
ARTICLE VARCHAR(50),
QUANTITY INT,
LOCATION VARCHAR(50),
SEQUENCE INT
);
INSERT INVENTORY (ARTICLE, QUANTITY,LOCATION,SEQUENCE)
VALUES ('ITEM01', 10, 'LOC01',1), ('ITEM01', 30, 'LOC02',2),
('ITEM01', 30, 'LOC03',3), ('ITEM02', 2, 'LOC02',2),
('ITEM02', 10, 'LOC03',3), ('ITEM03', 1, 'LOC01',1),
('ITEM03', 5, 'LOC02',2)`
我正在做的是:
首先从库存中拆分成一个表
可裂
DROP TABLE IF EXISTS SPLITTABLE
CREATE TABLE SPLITTABLE
(
ARTICLE VARCHAR(50),
QUANTITY INT,
LOCATION VARCHAR(50),
IDORDER INT,
SEQUENCE INT
);
SPLIT
WITH RTE (Vals) AS
(
SELECT 1
UNION ALL
SELECT 1 + Vals
FROM RTE
WHERE Vals < 500
)
INSERT INTO SPLITTABLE (ARTICLE, QUANTITY, LOCATION, IDORDER,SEQUENCE)
SELECT ARTICLE,1 AS QUANTITY,LOCATIONS,0 AS IDORDER, SEQUENCE
FROM INVENTORY INV
INNER JOIN RTE R ON R.Vals <= INV.Quantity
OPTION (maxrecursion 0);
- 结果
88行,数量为1 --88因为ITEM01 70 ITEM02 12和ITEM03 6
SELECT * FROM SPLITTABLE
ARTICLE QUANTITY LOCATION IDORDER SEQUENCE
ITEM01 1 LOC01 0 1
ITEM01 1 LOC02 0 2
ITEM01 1 LOC03 0 3
ITEM02 1 LOC02 0 2
ITEM02 1 LOC03 0 3
ITEM03 1 LOC01 0 1
ITEM03 1 LOC02 0 2
ITEM01 1 LOC01 0 1
ITEM01 1 LOC02 0 2
...直到88行(IDORDER在0中因为它还没有被赋值)
分裂后我分配了一个Idorder(在声明语句中这是我想要避免的)
DECLARE @LIMIT INT =25;
DECLARE @ORDER INT = 1;
DECLARE @ARTICLE VARCHAR(50)='ITEM01';
WITH CTE AS
(
SELECT
ARTICLE, QUANTITY, LOCATION, IDORDER,
RUNNINGTOTAL = SUM(QUANTITY) OVER (PARTITION BY ARTICLE ORDER BY
LOCATION
ROWS UNBOUNDED PRECEDING)
FROM
SPLITTABLE
WHERE
ARTICLE = @ARTICLE AND IDORDER =0
), TOTAL AS
(
SELECT
ARTICLE, QUANTITY, LOCATION, IDORDER = @ORDER
FROM
CTE
WHERE
RUNNINGTOTAL <= @LIMIT
)
UPDATE CTE
SET IDORDER = T.IDORDER
FROM TOTAL AS T
WHERE RUNNINGTOTAL <= @LIMIT;
- 结果
SPLITTABLE的25行,ITEM01标记为IDORDER 1
SELECT * FROM SPLITTABLE WHERE ARTICLE ='ITEM01' ORDER BY SEQUENCE ASC
ARTICLE QUANTITY LOCATION IDORDER SEQUENCE
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC01 1 1
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
ITEM01 1 LOC02 1 2
- 其余行为0,因为我只选择ITEM01,数量为25 - 从LOC01(序列1)只有10个,从LOC02(序列2)只有15个
- 在更改每个项目,订单和数量的所有声明语句后,我可以看到结果
- 通过此查询,您可以获得我想要的内容
SELECT ARTICLE,SUM(QUANTITY) AS QUANTITY,LOCATION,IDORDER FROM SPLITTABLE
WHERE IDORDER<>0 GROUP BY ARTICLE,IDORDER,LOCATION ORDER BY IDORDER ASC
通过这些查询,我得到了我需要的信息,但是我遇到了一些问题
拆分部分会将所有文章纳入SPLITTABLE
问题,当我有订单要求1篇文章但该文章的库存中有&gt; 1000需要大量的时间和资源
完成拆分后,我会指定idorder
,但我必须手动为每篇文章和每个订单执行此操作
我必须提前感谢您的所有意见和帮助
如果您需要更多信息,请告诉我
答案 0 :(得分:0)
您可以使用游标。
我在示例中使用了表变量,因此您必须稍微更改一下代码(删除@)
如果清单中没有足够的项目,NULL将被插入LOCATION列,必要时将其删除。
我没有添加数量限制,您必须确保订单不能包含超过限制,因为让客户订购更多然后发送的订单少于他的订单似乎具有误导性。除非我误解了意图。
DECLARE @SALESORDER TABLE
(
IDORDER INT,
ARTICLE VARCHAR(50),
QUANTITY INT
);
INSERT @SALESORDER (IDORDER, ARTICLE, QUANTITY)
VALUES (1, 'ITEM01', 25), (1, 'ITEM02', 10),(1, 'ITEM14', 1),(2, 'ITEM00', 10),
(2, 'ITEM01', 70), (3, 'ITEM01', 5),
(3, 'ITEM03', 4)
DECLARE @INVENTORY TABLE
(
ARTICLE VARCHAR(50),
QUANTITY INT,
LOCATION VARCHAR(50)
);
INSERT @INVENTORY (ARTICLE, QUANTITY,LOCATION)
VALUES ('ITEM01', 10, 'LOC01'), ('ITEM01', 30, 'LOC02'),
('ITEM01', 30, 'LOC03'), ('ITEM02', 2, 'LOC02'),
('ITEM02', 10, 'LOC03'), ('ITEM03', 1, 'LOC01'),
('ITEM03', 5, 'LOC02'), ('ITEM01', 0, 'LOC04')
DECLARE @SPLITTABLE TABLE
(
ARTICLE VARCHAR(50),
QUANTITY INT,
LOCATION VARCHAR(50),
IDORDER INT
);
---------------------------------------------------------------------------
DECLARE so_cur CURSOR local fast_forward
FOR
SELECT so.ARTICLE,so.QUANTITY,so.IDORDER FROM @SALESORDER as so
ORDER BY so.ARTICLE,so.IDORDER
;
DECLARE inv_cur CURSOR local fast_forward
FOR
SELECT inv.ARTICLE,inv.QUANTITY,inv.[LOCATION] FROM @INVENTORY as inv
ORDER BY inv.ARTICLE,inv.[LOCATION]
;
declare @so_ARTICLE varchar(50);
declare @so_QUANTITY int;
declare @so_IDORDER int;
declare @inv_ARTICLE varchar(50);
declare @inv_QUANTITY int;
declare @inv_LOCATION varchar(50);
declare @nextOrder bit = 1;
declare @nextInv bit = 1;
declare @outOfInv bit = 0;
open so_cur
open inv_cur
WHILE 1=1
BEGIN
IF @nextOrder = 1
BEGIN
FETCH NEXT from so_cur
INTO
@so_ARTICLE,
@so_QUANTITY,
@so_IDORDER
;
SET @nextOrder = 0;
if @@FETCH_STATUS = -1 break;
END
IF @outOfInv = 0 AND @nextInv = 1
BEGIN
FETCH NEXT from inv_cur
INTO
@inv_ARTICLE,
@inv_QUANTITY,
@inv_LOCATION
;
SET @nextInv = 0;
if @@FETCH_STATUS = -1
BEGIN
SET @outOfInv = 1;
PRINT N'NOT ENOUGH ITEMS IN INVENTORY'
END
END
IF @outOfInv = 0 AND @inv_ARTICLE < @so_ARTICLE
BEGIN
SET @nextInv = 1;
END
ELSE IF @outOfInv = 1 OR @inv_ARTICLE > @so_ARTICLE
BEGIN
PRINT N'NOT ENOUGH ITEMS IN INVENTORY, YOU MIGHT WANT TO INSERT LOCATION=NULL TO THE SPLITTABLE';
INSERT INTO @SPLITTABLE (ARTICLE,QUANTITY,LOCATION,IDORDER) VALUES (@so_ARTICLE,@so_QUANTITY,NULL,@so_IDORDER)
SET @nextOrder = 1;
END
ELSE
BEGIN
IF @so_QUANTITY < @inv_QUANTITY
BEGIN
IF @so_QUANTITY >0
BEGIN
INSERT INTO @SPLITTABLE (ARTICLE,QUANTITY,LOCATION,IDORDER) VALUES (@so_ARTICLE,@so_QUANTITY,@inv_LOCATION,@so_IDORDER)
SET @inv_QUANTITY -= @so_QUANTITY
END
SET @nextOrder = 1;
END
ELSE IF @so_QUANTITY = @inv_QUANTITY
BEGIN
IF @so_QUANTITY >0
BEGIN
INSERT INTO @SPLITTABLE (ARTICLE,QUANTITY,LOCATION,IDORDER) VALUES (@so_ARTICLE,@so_QUANTITY,@inv_LOCATION,@so_IDORDER)
END
SET @nextOrder = 1;
SET @nextInv = 1;
END
ELSE
BEGIN
IF @inv_QUANTITY >0
BEGIN
INSERT INTO @SPLITTABLE (ARTICLE,QUANTITY,LOCATION,IDORDER) VALUES (@so_ARTICLE,@inv_QUANTITY,@inv_LOCATION,@so_IDORDER)
SET @so_QUANTITY -= @inv_QUANTITY
END
SET @nextInv = 1;
END
END
END
CLOSE so_cur;
DEALLOCATE so_cur;
CLOSE inv_cur;
DEALLOCATE inv_cur;
-----------------------------------------------------------------------
SELECT * FROM @SPLITTABLE ORDER BY IDORDER,ARTICLE