April 4, 2014 at 6:53 am
I would like to create a view based on the following sql statement. I understand that I cannot declare a variable for use in a view but how do I go about it? Otherwise I have to hard code in the value from ctlfil where recid=24
declare @retained varchar(16)
select @retained=nomcode from ctlfil where recid=24
SELECT dbo.nomfil.nomcode, ISNULL(calc.val, 0) AS ytdper, calc.costcentre
FROM dbo.nomfil LEFT OUTER JOIN
(SELECT CASE WHEN nomfil_1.type IN (3, 4) THEN nomtrn.nomcode ELSE @retained END AS nomcode, SUM(dbo.nomtrn.val * (1 - 2 * dbo.nomtrn.crddbt)) AS val,
dbo.nomtrn.costcentre
FROM dbo.nomtrn INNER JOIN
dbo.nomfil AS nomfil_1 ON dbo.nomtrn.nomcode = nomfil_1.nomcode
WHERE (dbo.nomtrn.period <
(SELECT glpernum / 100 * 100 AS Expr1
FROM dbo.perfil))
GROUP BY CASE WHEN nomfil_1.type IN (3, 4) THEN nomtrn.nomcode ELSE @retained END, dbo.nomtrn.costcentre) AS calc ON calc.nomcode = dbo.nomfil.nomcode
April 4, 2014 at 7:04 am
This should work as long as you don't have multiple rows being returned from that subquery
SELECT dbo.nomfil.nomcode ,
ISNULL(calc.val, 0) AS ytdper ,
calc.costcentre
FROM dbo.nomfil
LEFT OUTER JOIN ( SELECT CASE WHEN nomfil_1.type IN ( 3, 4 )
THEN nomtrn.nomcode
ELSE ( SELECT nomcode
FROM ctlfil
WHERE recid = 24
)
END AS nomcode ,
SUM(dbo.nomtrn.val * ( 1 - 2 * dbo.nomtrn.crddbt )) AS val ,
dbo.nomtrn.costcentre
FROM dbo.nomtrn
INNER JOIN dbo.nomfil AS nomfil_1 ON dbo.nomtrn.nomcode = nomfil_1.nomcode
WHERE ( dbo.nomtrn.period < ( SELECT
glpernum / 100 * 100 AS Expr1
FROM
dbo.perfil
) )
GROUP BY CASE WHEN nomfil_1.type IN ( 3, 4 )
THEN nomtrn.nomcode
ELSE ( SELECT nomcode
FROM ctlfil
WHERE recid = 24
)
END ,
dbo.nomtrn.costcentre
) AS calc ON calc.nomcode = dbo.nomfil.nomcode
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
April 4, 2014 at 7:09 am
Thanks I tried that but I can't use the subquery (SELECT nomcode FROM ctlfil WHERE recid = 24) in the GROUP BY clause
April 4, 2014 at 7:30 am
I can create a user defined function to get the value but not sure how I can use that either?
CREATE FUNCTION dbo.udf_retained_nomcode()
RETURNS @ret TABLE (col VARCHAR (16))
AS
BEGIN
DECLARE @retained varchar(16);
SELECT @retained=nomcode from ctlfil where recid=24;
INSERT INTO @ret SELECT @retained;
RETURN;
END;
GO
SELECT * FROM dbo.udf_retained_nomcode();
GO
April 4, 2014 at 7:34 am
phingers (4/4/2014)
Thanks I tried that but I can't use the subquery (SELECT nomcode FROM ctlfil WHERE recid = 24) in the GROUP BY clause
Why not?
The scalar function will do the same thing the subquery does, just much, much slower.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
April 4, 2014 at 8:37 am
this is basically the same solution as Gails in a different format; it's just a CROSS JOINED CTE to get the variable instead of a direct sub select.
CREATE VIEW myVIEW
AS
WITH MyCTE
AS (SELECT TOP 1
nomcode AS RetainedVariable
FROM ctlfil
WHERE recid = 24
ORDER BY
nomcode)
SELECT
dbo.nomfil.nomcode,
ISNULL(calc.val, 0) AS ytdper,
calc.costcentre
FROM dbo.nomfil
LEFT OUTER JOIN (SELECT
CASE
WHEN nomfil_1.type IN ( 3, 4 )
THEN
nomtrn.nomcode
ELSE
MyCTE.RetainedVariable
END AS nomcode,
SUM(dbo.nomtrn.val * ( 1 - 2 * dbo.nomtrn.crddbt )) AS val,
dbo.nomtrn.costcentre
FROM dbo.nomtrn
INNER JOIN dbo.nomfil AS nomfil_1
ON dbo.nomtrn.nomcode = nomfil_1.nomcode
CROSS JOIN MyCTE --there better be only one row!
WHERE ( dbo.nomtrn.period < (SELECT
glpernum / 100 * 100 AS Expr1
FROM dbo.perfil) )
GROUP BY
CASE
WHEN nomfil_1.type IN ( 3, 4 )
THEN
nomtrn.nomcode
ELSE
MyCTE.RetainedVariable
END,
dbo.nomtrn.costcentre) AS calc
ON calc.nomcode = dbo.nomfil.nomcode
Lowell
April 4, 2014 at 8:57 am
Thanks but when I try this it returns 'mutipart identifier MyCTE.RetainedVariable could not be bound'?
April 9, 2014 at 5:39 am
I finally got this to create the view successfully with the following code:
WITH MyCTE AS (SELECT TOP (1) nomcode AS Retained
FROM dbo.ctlfil
WHERE (recid = 24)
ORDER BY Retained)
SELECT dbo.nomfil.nomcode, ISNULL(calc.val, 0) AS ytdper, calc.costcentre
FROM dbo.nomfil LEFT OUTER JOIN
(SELECT CASE WHEN nomfil_1.type IN (3, 4) THEN nomtrn.nomcode ELSE MyCTE_1.Retained END AS nomcode,
SUM(dbo.nomtrn.val * (1 - 2 * dbo.nomtrn.crddbt)) AS val, dbo.nomtrn.costcentre
FROM dbo.nomtrn INNER JOIN
dbo.nomfil AS nomfil_1 ON dbo.nomtrn.nomcode = nomfil_1.nomcode CROSS JOIN
MyCTE AS MyCTE_1
WHERE (dbo.nomtrn.period <
(SELECT glpernum / 100 * 100 AS Expr1
FROM dbo.perfil))
GROUP BY CASE WHEN nomfil_1.type IN (3, 4) THEN nomtrn.nomcode ELSE MyCTE_1.Retained END, dbo.nomtrn.costcentre) AS calc ON
calc.nomcode = dbo.nomfil.nomcode
Thanks for the help everyone
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply