[英]Show rows <= according to another table quantity SQL (T-SQL)
I've been trying to get the simplest way to get a query from different tables, but only showing the quantity according to another table 我一直在尝试获得从不同表中查询的最简单方法,但是仅根据另一张表显示数量
-- I want to create a Pickroute Report -- the pickroute will have an idorder, article, quantity and location -我要创建一个取货路线报告-取货路线将具有idorder,商品,数量和位置
-- If I have an order that needs 25 ITEM01 -- I will take 10 from LOC01 and 15 from LOC02 -- All the locatios have a sequence -- Once I complete the 25 I need to update the IDORDER column in SPLITTABLE -如果我的订单需要25个ITEM01-我将从LOC01中获取10个订单,从LOC02中获取15个订单-所有位置都有一个序列-完成25个订单后,我需要更新SPLITTABLE中的IDORDER列
Let me explain 让我解释
I have the following tables 我有下表
SALESORDER table: SALESORDER表:
IDORDER ARTICLE QUANTITY
----------------------------
1 ITEM01 25
1 ITEM02 10
2 ITEM01 20
3 ITEM01 5
3 ITEM03 4
INVENTORY table: 库存表:
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
What I am trying to get is the following 我想要得到的是以下内容
OPORDER table: 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
Now let me show you what I'm doing to get it done (at least trying to do it). 现在,让我向您展示我正在做些什么(至少尝试这样做)。
Schema : 架构 :
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)
INVENTORY 库存
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)`
What I'm doing is: 我正在做的是:
first split into one piece table from the inventory 首先从库存拆分成一张桌子
SPLITTABLE 可分割
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);
--Result - 结果
88 rows with quantity 1 --88 Because ITEM01 70 ITEM02 12 and ITEM03 6 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
... until 88 rows(IDORDER is in 0 because it is not asigned yet) ...直到88行(IDORDER处于0,因为尚未分配)
After split I assign an Idorder(On the declare statements this is what I want to avoid) 拆分后,我分配一个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;
--Result - 结果
25 rows from SPLITTABLE with ITEM01 marked as IDORDER 1 来自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
-- The rest of the rows are in 0 because I only select ITEM01 and quantity 25 it --takes only 10 from the LOC01(sequence 1) and 15 from LOC02(sequence 2) -其余的行都在0中,因为我只选择了ITEM01并将其数量定为25-从LOC01(序列1)中只取10个,从LOC02(序列2)中取15个
--After changing all the declare statements for each item, order and quantity I can see the result -更改每个项目,订单和数量的所有声明语句后,我可以看到结果
--With this query you get what I want -通过此查询您得到我想要的
SELECT ARTICLE,SUM(QUANTITY) AS QUANTITY,LOCATION,IDORDER FROM SPLITTABLE
WHERE IDORDER<>0 GROUP BY ARTICLE,IDORDER,LOCATION ORDER BY IDORDER ASC
With these queries I get the information I need but I have some problems 通过这些查询,我可以获得所需的信息,但是我遇到了一些问题
The split part takes all the articles into the SPLITTABLE
the problem is when I have an order asking for 1 article but in the inventory for that article has > 1000 it takes a lot of time and resources 拆分的部分将所有文章都放入
SPLITTABLE
,问题是当我有一个订单要购买1篇文章,但该文章的库存中有> 1000时,这需要大量时间和资源
Once the split is done, I assign idorder
but I had to do it manually for each article and each order 拆分完成后,我分配了
idorder
但是我必须为每篇文章和每个订单手动进行
I have to thank you in advance for all your comments and help 我必须提前感谢您的所有评论和帮助
In case you need more information, let me know 如果您需要更多信息,请告诉我
You can use cursors. 您可以使用游标。
I used table variables in the example so you'll have to change a code a little bit (remove @) 我在示例中使用了表变量,因此您必须稍微更改一下代码(删除@)
When there is not enough items in the inventory the NULL will be inserted into the LOCATION column, remove this if necessary. 如果库存中没有足够的物品,则NULL将插入到LOCATION列中,如有必要,将其删除。
I didn't add quantity limit, you'll have to make sure that the order can't contain more than the limit because it seems misleading to let the customer order more and then send less than he ordered. 我没有添加数量限制,您必须确保订单中所包含的数量不能超过限制,因为让客户订购更多然后发送的数量少于订购数量似乎具有误导性。 Unless I misunderstood the intent.
除非我误解了意图。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.