2017-01-23 66 views
-1

数量我有2个疑问是这样的:更新记录依赖于SQL

select 
    F_In_Out_Date , 
    F_QTY, F_lot_number, F_BillOf_entryNumber 
from 
    T_Tra_Transaction 
where 
    F_lot_number = '160427A161' 
    and F_Stock_Type = 'IN' 

select 
    F_In_Out_Date , 
    F_QTY, F_lot_number, F_BillOf_entryNumber 
from 
    T_Tra_Transaction 
where 
    F_lot_number = '160427A161' 
    and F_Stock_Type = 'out' 

我的输出是这样的:

enter image description here

我的第一个查询显示在数量和我的第二个查询显示出数量取决于我的BOE号码。在我的结果中,第一个100个数量来自Billof条目编号14-2-4-15451983,所以在我的外出状态查询中,我需要更新第一个100个数量以上的billof entry number。另外70个数量需要更新其他账单号码(14-2-4-15546475)。我怎样才能做到这一点?

我作了一个查询,但是这是更新所有记录与第一个条目号码。

update tout 
set F_BillOf_entryNumber = tin.F_BillOf_entryNumber 
from 
    (select 
     F_QTY, F_lot_number, F_BillOf_entryNumber, 
     rn = row_number() over (partition by F_QTY, F_lot_number order by F_In_Out_Date desc) 
    from 
     T_Tra_Transaction 
    where 
     F_Stock_Type = 'out') tout 
join 
    (select 
     F_QTY, F_lot_number, F_BillOf_entryNumber, 
     rn = row_number() over (partition by F_QTY, F_lot_number order by F_In_Out_Date desc) 
    from 
     T_Tra_Transaction 
    where 
     F_Stock_Type = 'IN') tin on tout.F_lot_number = tin.F_lot_number 
+1

从表'T_Tra_Transaction'和'tout'提供一些示例数据。同时提供您正在寻找的预期结果。 – Viki888

+0

预期的结果将有助于描述以了解需求。 –

+0

@ Viki888 in out status first 100 qty我要更新第一个BOE号码和另一个70数量我想更新第二个BOE号码 – user3262364

回答

0

它有些什么复杂。你需要一个递归CTE来实现它。

以上部分的架构:

CREATE TABLE #T_TRA_TRANSACTION (F_Id INT IDENTITY PRIMARY KEY 
,F_IN_OUT_DTE DATETIME 
,F_QTY INT 
,F_LOT_NUMBER VARCHAR(50) 
,F_BILLOF_ENTRYNUMBER VARCHAR(50) 
,F_STOCK_TYPE VARCHAR(10)) 


INSERT INTO #T_TRA_TRANSACTION 

SELECT '2016-05-31',15,'160427A161','14-2-4-15451983','IN' 
UNION ALL 
SELECT '2016-05-31',5,'160427A161','14-2-4-15451983','IN' 
UNION ALL 
SELECT '2016-08-02',10,'160427A161','14-2-4-15546475','IN' 
UNION ALL 
SELECT '2016-08-02',10,'160427A161','14-2-4-15546475','IN' 
UNION ALL 
SELECT '2016-08-02',5,'160427A161','14-2-4-15546475','IN' 

UNION ALL 
SELECT '2016-08-14',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-14',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-14',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-14',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-18',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-18',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-18',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-18',5,'160427A161','14-2-4-15546475','OUT' 
UNION ALL 
SELECT '2016-08-18',5,'160427A161','14-2-4-15546475','OUT' 

并尝试下面的查询。我加入了每个CTE的中间结果对了解我们正在获取从中

;WITH CTE_BILL_WISE AS(
SELECT 
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) SNO_IN 
,SUM(F_QTY) IN_QTY 
, F_BILLOF_ENTRYNUMBER 
FROM 
    #T_TRA_TRANSACTION 
WHERE 
    F_LOT_NUMBER = '160427A161' 
    AND F_STOCK_TYPE = 'IN' 
GROUP BY F_BILLOF_ENTRYNUMBER 

/* RESULT OF CTE_BILL_WISE 
+--------+--------+----------------------+ 
| SNO_IN | IN_QTY | F_BILLOF_ENTRYNUMBER | 
+--------+--------+----------------------+ 
|  1 |  20 | 14-2-4-15451983  | 
|  2 |  25 | 14-2-4-15546475  | 
+--------+--------+----------------------+ 

*/ 

) 
,CTE_BILL_QTY_RANGE AS 
(
    SELECT SNO_IN, F_BILLOF_ENTRYNUMBER, 0 START_QTY ,IN_QTY AS END_QTY FROM CTE_BILL_WISE WHERE SNO_IN = 1 
    UNION ALL 
    SELECT C4.SNO_IN+1,C.F_BILLOF_ENTRYNUMBER, C4.END_QTY+1,C4.END_QTY+ C.IN_QTY FROM CTE_BILL_QTY_RANGE C4 
    INNER JOIN CTE_BILL_WISE C ON C4.SNO_IN+1 = C.SNO_IN 

    /* RESULT OF CTE_BILL_QTY_RANGE 
    +--------+----------------------+-----------+---------+ 
    | SNO_IN | F_BILLOF_ENTRYNUMBER | START_QTY | END_QTY | 
    +--------+----------------------+-----------+---------+ 
    |  1 | 14-2-4-15451983  |   0 |  20 | 
    |  2 | 14-2-4-15546475  |  21 |  45 | 
    +--------+----------------------+-----------+---------+ 
    */ 

) 

,CTE_OUT_TYPE AS 
(
    SELECT F_Id , 
    F_QTY 
    ,ROW_NUMBER() OVER(ORDER BY F_Id) SNO_OUT 
    FROM #T_TRA_TRANSACTION 
    WHERE F_LOT_NUMBER = '160427A161' 
    AND F_STOCK_TYPE = 'OUT' 

    /* RESULT OF CTE_OUT_TYPE 
    +------+-------+---------+ 
    | F_Id | F_QTY | SNO_OUT | 
    +------+-------+---------+ 
    | 6 |  5 |  1 | 
    | 7 |  5 |  2 | 
    | 8 |  5 |  3 | 
    | 9 |  5 |  4 | 
    | 10 |  5 |  5 | 
    | 11 |  5 |  6 | 
    | 12 |  5 |  7 | 
    | 13 |  5 |  8 | 
    | 14 |  5 |  9 | 
    +------+-------+---------+ 
    */ 

) 
,CTE_OUT_QTY_SUM AS 
(
    SELECT SNO_OUT, F_Id,F_QTY FROM CTE_OUT_TYPE WHERE SNO_OUT = 1 
    UNION ALL 
    SELECT C2.SNO_OUT, C2.F_Id,F_QTY = C3.F_QTY+C2.F_QTY FROM CTE_OUT_QTY_SUM C3 
    INNER JOIN CTE_OUT_TYPE C2 ON C3.SNO_OUT+1 = C2.SNO_OUT 

    /* RESULT OF CTE_OUT_QTY_SUM 
    +---------+------+-------+ 
    | SNO_OUT | F_Id | F_QTY | 
    +---------+------+-------+ 
    |  1 | 6 |  5 | 
    |  2 | 7 | 10 | 
    |  3 | 8 | 15 | 
    |  4 | 9 | 20 | 
    |  5 | 10 | 25 | 
    |  6 | 11 | 30 | 
    |  7 | 12 | 35 | 
    |  8 | 13 | 40 | 
    |  9 | 14 | 45 | 
    +---------+------+-------+ 
    */ 

) 

SELECT C3.F_Id, C4.F_BILLOF_ENTRYNUMBER FROM CTE_OUT_QTY_SUM C3 
INNER JOIN CTE_BILL_QTY_RANGE C4 ON C3.F_QTY BETWEEN C4.START_QTY AND C4.END_QTY 

    /* RESULT OF FINAL CTE 
    +------+----------------------+ 
    | F_Id | F_BILLOF_ENTRYNUMBER | 
    +------+----------------------+ 
    | 6 | 14-2-4-15451983  | 
    | 7 | 14-2-4-15451983  | 
    | 8 | 14-2-4-15451983  | 
    | 9 | 14-2-4-15451983  | 
    | 10 | 14-2-4-15546475  | 
    | 11 | 14-2-4-15546475  | 
    | 12 | 14-2-4-15546475  | 
    | 13 | 14-2-4-15546475  | 
    | 14 | 14-2-4-15546475  | 
    +------+----------------------+ 
    */ 

您可以更改最后选择要更新一样

UPDATE #T_TRA_TRANSACTION SET #T_TRA_TRANSACTION.F_BILLOF_ENTRYNUMBER = C4.F_BILLOF_ENTRYNUMBER 
FROM CTE_OUT_QTY_SUM C3 
INNER JOIN CTE_BILL_QTY_RANGE C4 ON C3.F_QTY BETWEEN C4.START_QTY AND C4.END_QTY 
INNER JOIN #T_TRA_TRANSACTION ON #T_TRA_TRANSACTION.F_Id = C3.F_Id 
+0

亲爱的先生..如果我不创建临时表我不能做? – user3262364

+0

无需创建临时表。只是为我的测试目的而创建的。您可以用您的实际表替换Temptable @ user3262364 –

0

我不知道下面的查询是否匹配你的要求。 可能对您有所帮助,此查询基于SQL Server 2012+。 ID = 9正在加我。

CREATE TABLE #ti(F_In_Out_Date DATETIME,INQTY FLOAT ,F_lot_number VARCHAR(100),BOE VARCHAR(100)) 
INSERT INTO #ti 
SELECT '2016-05-31',80,'1606427A161','14-2-4-15451983' UNION ALL 
SELECT '2016-05-31',15,'1606427A161','14-2-4-15451983' UNION ALL 
SELECT '2016-05-31',5,'1606427A161','14-2-4-15451983' UNION ALL 
SELECT '2016-08-02',60,'1606427A161','14-2-4-15546475' UNION ALL 
SELECT '2016-08-02',10,'1606427A161','14-2-4-15546475' 
--DROP TABLE #to 
CREATE TABLE #to(ID INT ,F_In_Out_Date DATETIME,OUTTY FLOAT ,F_lot_number VARCHAR(100),BOE VARCHAR(100)) 
INSERT INTO #to 
SELECT 1,'2016-08-14',5,'1606427A161',NULL UNION ALL 
SELECT 2,'2016-08-14',5,'1606427A161',NULL UNION ALL 
SELECT 3,'2016-08-14',5,'1606427A161',NULL UNION ALL 
SELECT 4,'2016-08-18',5,'1606427A161',NULL UNION ALL 
SELECT 5,'2016-08-18',5,'1606427A161',NULL UNION ALL 
SELECT 6,'2016-08-18',5,'1606427A161',NULL UNION ALL 
SELECT 7,'2016-08-18',5,'1606427A161',NULL UNION ALL 
SELECT 8,'2016-08-18',5,'1606427A161',NULL UNION ALL 
SELECT 9,'2016-08-12',100,'1606427A161',NULL 
UPDATE t SET t.BOE=x.BOE 
--SELECT t.*,x.*,o.CurrentOutQty 
FROM #to AS t 
INNER JOIN (
    SELECT *, SUM(OUTTY)OVER(PARTITION BY F_lot_number ORDER BY F_In_Out_Date desc) AS CurrentOutQty 
    FROM #to AS oo 
) AS o ON o.ID=t.ID 
CROSS APPLY (
    SELECT TOP 1 i.BOE,i.CurrentInQty 
    FROM (
     SELECT *,SUM(INQTY)OVER(PARTITION BY F_lot_number ORDER BY F_In_Out_Date desc) AS CurrentInQty 
     FROM #ti AS ii WHERE ii.F_lot_number=o.F_lot_number 
    ) AS i WHERE i.CurrentInQty>=o.CurrentOutQty ORDER BY i.CurrentInQty 
) AS x 

SELECT * FROM #to 
 
ID   F_In_Out_Date   OUTTY     F_lot_number   BOE 
----------- ----------------------- ---------------------- -------------------- -------------------- 
1   2016-08-14 00:00:00.000 5      1606427A161   1606427A161 
2   2016-08-14 00:00:00.000 5      1606427A161   1606427A161 
3   2016-08-14 00:00:00.000 5      1606427A161   1606427A161 
4   2016-08-18 00:00:00.000 5      1606427A161   1606427A161 
5   2016-08-18 00:00:00.000 5      1606427A161   1606427A161 
6   2016-08-18 00:00:00.000 5      1606427A161   1606427A161 
7   2016-08-18 00:00:00.000 5      1606427A161   1606427A161 
8   2016-08-18 00:00:00.000 5      1606427A161   1606427A161 
9   2016-08-12 00:00:00.000 100     1606427A161   1606427A161 
+0

而不是创建临时表,我无法更新? – user3262364