简体   繁体   中英

SQL Server Update with join from same table

I have managed to create my table from the flat txt file but due to the layout of this the time stamp is not in the right place. The file reads like this:

13-Feb-17 01:14

N1 SUNDRY 331/6203 ASTOCK 000000  PICK   111111    0     3   0   0 268          

13-Feb-17 01:15

N1 SUNDRY 397/5747 ASTOCK 000000  PICK   111111    0     2   0   0 268          

13-Feb-17 06:09

MP GRENDZ 606/0484        000000         060472    0     0   0   0 193
A5 GRENDZ 606/0484        000000         060472    1    26   5   0   3
MP GRENDZ 346/9789        000000         060704    1     0   5   0 304
A5 GRENDZ 346/9789        000000         060704    1     8   5   0   3

So when I import in to the new table with:

    -- SELECT DATABASE
    USE [CHDS_Sandbox]
    GO
    -- TRUNCATE TABLE
    TRUNCATE TABLE [dbo].[LogScan]
    GO
-- INSERT NEW DATA
INSERT INTO [dbo].[LogScan]
            (move_type, program, cat, from_loc, pallet_no, to_loc, grds, pallets, items, tme, clk_num, id_num, movement_key, move_stamp, t_stamp)
SELECT
-- 0 AS id_als,
CASE WHEN SUBSTRING(Field1,1,2) BETWEEN '0' AND '99' THEN '' ELSE SUBSTRING(Field1,1,2) END AS move_type,
CASE WHEN SUBSTRING(Field1,4,6) LIKE '%-%' THEN '' ELSE SUBSTRING(Field1,4,6) END AS program,
CASE WHEN SUBSTRING(Field1,11,8) LIKE '%:%' THEN '' ELSE SUBSTRING(Field1,11,8) END AS cat,
SUBSTRING(Field1,20,6) AS from_loc,
0+SUBSTRING(Field1,27,6) AS pallet_no,
SUBSTRING(Field1,35,6) AS to_loc,
0+SUBSTRING(Field1,42,6) AS grds,
0+SUBSTRING(Field1,49,4) AS pallets,
0+SUBSTRING(Field1,54,5) AS items,
0+SUBSTRING(Field1,60,3) AS tme,
0+SUBSTRING(Field1,64,3) AS clk_num,
0+SUBSTRING(Field1,68,4) AS id_num,
SUBSTRING(Field1,72,9) AS movement_key,
CASE
    WHEN SUBSTRING(Field1,4,3)='JAN' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='FEB' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='MAR' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='APR' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='MAY' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='JUN' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='JUL' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='AUG' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='SEP' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='OCT' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='NOV' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
    WHEN SUBSTRING(Field1,4,3)='DEC' THEN CONVERT(DATETIME2(0),(SUBSTRING(Field1,1,15)),101)
END AS move_stamp,
GETDATE() AS t_stamp
FROM [CHDS_Staging].[dbo].[csv_ImportedData]
WHERE SUBSTRING(Field1,11,8) LIKE '%/%' OR SUBSTRING(Field1,11,5) LIKE '%:%'   AND SUBSTRING(Field1,27,6) NOT LIKE '%:%'
GO

but this gives me : enter image description here

I need the move stamp in each of the cells below it until it changes.

Any help on this would be great.

This is what worked in MySQL:

   UPDATE dbo.LogScan t1
   JOIN (
   SELECT id_als, @s:=IF(move_stamp IS NULL, @s, move_stamp) move_stamp
   FROM (SELECT * 
   FROM dbo.LogScan 
   ORDER BY id_als) r,
   (SELECT @s:='') t
   ) t2
   ON t1.id_als = t2.id_als
   SET @t1.move_stamp = t2.move_stamp;

I have written the below query and I'm hoping that I don't have any syntax error. please check and see if this works for you. I assumed that your is-als column is an int column. also if you like to remove the empty rows like row 1,3,5,10 etc then include the where condition that is currently commented in the query you can use this query to update the rows

   WITH StampCTE AS (
      SELECT ([id-als]+1) AS id-als,move_stamp
      FROM [dbo].[LogScan]
      WHERE move_stamp IS NOT NULL
    )  
    SELECT
        T1.id_als,
        T1.move_type, 
        T1.program, 
        T1.cat, 
        T1.from_loc, 
        T1.pallet_no, 
        T1.to_loc, 
        T1.grds, 
        T1.pallets, 
        T1.items, 
        T1.tme, 
        T1.clk_num, 
        T1.id_num, 
        T1.movement_key, 
        T1.move_stamp ,
        T2.move_stamp AS [NEW COLUMN MOVED] ,  
        T1.t_stamp
    FROM [dbo].[LogScan] T1
    LEFT JOIN StampCTE T2 ON T1.id_als = T2.id-als
    --WHERE RTRIM(LTRIM(T1.move_type)) <> '' 

update statement:

I would first run the select and if you see that thats what you like then use the below:



    WITH StampCTE AS ( SELECT ([id_als]+1) AS id_als,move_stamp 
    FROM [dbo].[LogScan] WHERE move_stamp IS NOT NULL 
    ) 
    UPDATE T1 
    SET T1.move_stamp = T2.move_stamp 
    FROM [dbo].[LogScan] T1
    LEFT JOIN StampCTE T2 ON T1.id_als = T2.id_als

the below update statement updates each row from a row behind, it might be slow if you have alot of data:

DECLARE @ID INT;

WHILE (SELECT COUNT(*) FROM [dbo].[LogScan] WHERE move_stamp IS NULL) > 0
BEGIN

    SELECT TOP(1) @ID = id_als from [dbo].[LogScan]
    WHERE move_stamp IS NULL
    ORDER BY id_als; 

    WITH StampCTE AS ( 
    SELECT DISTINCT move_stamp 
    FROM [dbo].[LogScan] WHERE id_als = @ID-1
    ) 
    UPDATE [dbo].[LogScan] T1
    SET T1.move_stamp = StampCTE.move_stamp 

END


SELECT * FROM [dbo].[LogScan]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM