[英]Show rows <= according to another table quantity SQL (T-SQL)
我一直在嘗試獲得從不同表中查詢的最簡單方法,但是僅根據另一張表顯示數量
-我要創建一個取貨路線報告-取貨路線將具有idorder,商品,數量和位置
-如果我的訂單需要25個ITEM01-我將從LOC01中獲取10個訂單,從LOC02中獲取15個訂單-所有位置都有一個序列-完成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
現在,讓我向您展示我正在做些什么(至少嘗試這樣做)。
架構 :
銷售訂單
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
);
分裂
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篇文章,但該文章的庫存中有> 1000時,這需要大量時間和資源
拆分完成后,我分配了idorder
但是我必須為每篇文章和每個訂單手動進行
我必須提前感謝您的所有評論和幫助
如果您需要更多信息,請告訴我
您可以使用游標。
我在示例中使用了表變量,因此您必須稍微更改一下代碼(刪除@)
如果庫存中沒有足夠的物品,則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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.