Link to home
Start Free TrialLog in
Avatar of BFanguy
BFanguyFlag for United States of America

asked on

Help with a SQL Server subquery or stored procedure

Help with SQL SERVER 2008R2 view or stored procedure.

I have a view (CT_Work_Order_Warehouse_Headers_Pass_02) that the output looks like this:
BASE		LOT		SPLIT		SUB		SEQ		WAREHOUSE
CC181137.3		21		0		0		5		HOUMA
CC181137.3		21		0		0		10		TBD
CC181137.3		21		0		0		20		TBD
CC181137.3		21		0		0		30		PORT_ALLEN
CC181137.3		21		0		0		40		TBD
CC181137.3		21		0		0		50		HOUMA
CC181137.3		21		0		0		60		TBD
CC189999.3		1		0		1		10		PORT_ALLEN
CC189999.3		1		0		1		20		TBD
CC189999.3		1		0		1		30		TBD
CC189999.3		1		0		1		40		HOUMA
CC189999.3		1		0		1		50		TBD
CC181234		1		0		1		5		PORT_ALLEN
CC181234		1		0		1		10		TBD
CC181234		1		0		1		20		TBD

Open in new window


I need a view or stored procedure to make the data look like this:
BASE		LOT		SPLIT		SUB		SEQ		WAREHOUSE
CC181137.3		21		0		0		5		HOUMA
CC181137.3		21		0		0		10		HOUMA
CC181137.3		21		0		0		20		HOUMA
CC181137.3		21		0		0		30		PORT_ALLEN
CC181137.3		21		0		0		40		PORT_ALLEN
CC181137.3		21		0		0		50		HOUMA
CC181137.3		21		0		0		60		HOUMA
CC189999.3		1		0		1		10		PORT_ALLEN
CC189999.3		1		0		1		20		PORT_ALLEN
CC189999.3		1		0		1		30		PORT_ALLEN
CC189999.3		1		0		1		40		HOUMA
CC189999.3		1		0		1		50		HOUMA
CC181234		1		0		1		5		PORT_ALLEN
CC181234		1		0		1		10		PORT_ALLEN
CC181234		1		0		1		20		PORT_ALLEN

Open in new window


Note: Each starting SEQ will have a non 'TBD' warehouse for each different Base/Lot/Split/Sub
I know i need to go get the WAREHOUSE from the SEQ <= the current SEQ where it is not = 'TBD'

any help would be greatly appreciated.
Avatar of Raja Jegan R
Raja Jegan R
Flag of India image

With the sample of your data, this should do..
Kindly try converting this to a procedure as required..
SELECT base, LOT, SPLIT, SUB, SEQ
, CASE WHEN WareHouse = 'TBD' THEN (SELECT TOP 1 t2.WareHouse FROM CT_Work_Order_Warehouse_Headers_Pass_02 t2 WHERE t1.Base = t2.Base and t1.Lot = t2.Lot and t1.Split = t2.Split and t1.sub = t2.sub and t1.Seq > t2.Seq and t2.WareHouse <> 'TBD' ORDER BY t2.SEQ desc) ELSE Warehouse END
FROM CT_Work_Order_Warehouse_Headers_Pass_02 t1

Open in new window

Avatar of BFanguy

ASKER

Thanks Raja,
I got this to work, but it takes 49 seconds to return 13045 rows:
SELECT     WORKORDER_BASE_ID, WORKORDER_LOT_ID, WORKORDER_SPLIT_ID, WORKORDER_SUB_ID, SEQUENCE_NO, 
                      CASE WHEN Op_WareHouse = 'TBD' THEN
                          (SELECT     TOP 1 t2.Op_WareHouse
                            FROM          CT_WorkOrder_Operations_WareHouse_Pass_01 AS t2 WITH (NOLOCK)
                            WHERE      t1.WORKORDER_BASE_ID = t2.WORKORDER_BASE_ID AND t1.WORKORDER_LOT_ID = t2.WORKORDER_LOT_ID AND 
                                                   t1.WORKORDER_SPLIT_ID = t2.WORKORDER_SPLIT_ID AND t1.WORKORDER_SUB_ID = t2.WORKORDER_SUB_ID AND 
                                                   t1.SEQUENCE_NO > t2.SEQUENCE_NO AND t2.Op_WareHouse <> 'TBD'
                            ORDER BY t2.SEQUENCE_NO DESC) ELSE Op_WareHouse END AS Expr1
FROM         dbo.CT_WorkOrder_Operations_Warehouse_Pass_01 AS t1 WITH (NOLOCK)

Open in new window


I had written a function yesterday after posting the question that runs in 31 seconds:
ALTER FUNCTION [dbo].[fn_CT_OP_Warehouse]
    (
        @TYPE NCHAR(1) ,
        @BASE NVARCHAR(30) ,
        @LOT NVARCHAR(3) ,
        @SPLIT NVARCHAR(3) ,
        @SUB NVARCHAR(3) ,
        @SEQ smallint,
        @WAREHOUSE nvarchar(30)
    )
RETURNS NVARCHAR(30)

AS
    BEGIN
        DECLARE @MSEQ smallint;
        SELECT @MSEQ = MAX(CT_WorkOrder_Operations_Warehouse_Pass_01.SEQUENCE_NO) FROM CT_WorkOrder_Operations_Warehouse_Pass_01 WHERE WORKORDER_TYPE = @TYPE AND WORKORDER_BASE_ID = @BASE AND WORKORDER_LOT_ID = @LOT AND WORKORDER_SPLIT_ID = @SPLIT AND WORKORDER_SUB_ID = @SUB AND SEQUENCE_NO <= @SEQ AND OP_Warehouse not like N'TBD'
        DECLARE @OPWAREHOUSE NVARCHAR(30);
        SELECT @OPWAREHOUSE = OP_Warehouse FROM CT_WorkOrder_Operations_Warehouse_Pass_01 WHERE WORKORDER_TYPE = @TYPE AND WORKORDER_BASE_ID = @BASE AND WORKORDER_LOT_ID = @LOT AND WORKORDER_SPLIT_ID = @SPLIT AND WORKORDER_SUB_ID = @SUB AND SEQUENCE_NO = @MSEQ
        RETURN @OPWAREHOUSE
    END

Open in new window

The code above takes 2 select statements - so i figured maybe i could use your select statement in the function to speed it up but i can't get the select @OPWAREHOUSE = TOP 1... statement to work:
ALTER FUNCTION [dbo].[fn_CT_OPERATION_Warehouse]
    (
        @TYPE NCHAR(1) ,
        @BASE NVARCHAR(30) ,
        @LOT NVARCHAR(3) ,
        @SPLIT NVARCHAR(3) ,
        @SUB NVARCHAR(3) ,
        @SEQ smallint
    )
RETURNS NVARCHAR(30)

AS
    BEGIN
        DECLARE @OPWAREHOUSE NVARCHAR(30);
        SELECT @OPWAREHOUSE = TOP 1 Op_WareHouse FROM  CT_WorkOrder_Operations_WareHouse_Pass_01 WITH (NOLOCK) WHERE WORKORDER_BASE_ID = @BASE AND WORKORDER_LOT_ID = @LOT AND WORKORDER_SPLIT_ID = @SPLIT AND WORKORDER_SUB_ID = @SUB AND SEQUENCE_NO <= @SEQ AND Op_WareHouse <> 'TBD' ORDER BY SEQUENCE_NO DESC
        RETURN @OPWAREHOUSE
    END

Open in new window

SQL does not like the TOP in the select statement above.
any ideas?
ASKER CERTIFIED SOLUTION
Avatar of Raja Jegan R
Raja Jegan R
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of BFanguy

ASKER

thanks, will test for speed
Avatar of BFanguy

ASKER

thanks, this cut the time in half!
Welcome, glad to assist!!