SQL server can not accept median function - sql-server

I wrote this Median function but it is executing with errors.. Can someone guide me what's wrong in the code?
BEGIN
CREATE TABLE #ITEMORDERDETAILS
(
ITEM CHAR(15),
QTYSHP DECIMAL(21, 6),
RQDATE DATETIME
)
DECLARE #Median FLOAT
DECLARE #ITEM CHAR(15)
DECLARE #ORDERCNT INT
SET #ITEM=#ITEMN
INSERT #ITEMORDERDETAILS
SELECT ITEM,
QTYSHP,
RQDATE
FROM tbl123456
WHERE PRICE != '0'
AND SALESMN != 'WB'
AND RQDATE > ( getdate () - 180 )
AND ITEM = #ITEM
UNION
SELECT ITEM,
QTYSHP,
RQDATE
FROM tbl123
WHERE PRICE != '0'
AND SALESMN != 'WB'
AND RQDATE > ( getdate () - 180 )
AND ITEM = #ITEM
SELECT #ORDERCNT = count (1)
FROM #ITEMORDERDETAILS
--SELECT #ORDERCNT
SELECT #Median = ( sum(QTYSHP) / #ORDERCNT )
FROM #ITEMORDERDETAILS
SELECT #Median AS 'Median'
--SELECT * from #ITEMORDERDETAILS
DROP TABLE #ITEMORDERDETAILS
RETURN #Median
END
ERRORS
Msg 2772, Level 16, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 34 Cannot access temporary
tables from within a function.
Msg 2772, Level 16, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 35 Cannot access temporary
tables from within a function.
Msg 2772, Level 16, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 42 Cannot access temporary
tables from within a function.
Msg 156, Level 15, State 1, Procedure
f_Get_Average_Order_Size_Median, Line 46 Incorrect syntax near the
keyword 'SELECT'.

The reason is in your error message:
Line 34 Cannot access temporary tables from within a function
If you make a function, there are limits to what you can access.
However, if you use SQL Server 2012, you do not need to write your own median function but you can use PERCENTILE_DISC
PERCENTILE_DISC (0.5) WITHIN GROUP (ORDER BY XXXX)
OVER (PARTITION BY YYYY) AS Median

Related

How to delete 1000 rows at a time with SQL Server OPENQUERY

I need to delete rows in a link server's table, 1000 rows at a time.
My code is the following:
WHILE (SELECT COUNT(*) FROM OPENQUERY (SqlServerAcc, 'SELECT * FROM titles ') > 1000)
BEGIN
DELETE OPENQUERY (SqlServerAcc,
'SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber FROM tbl) t WHERE RowNumber <= 1000');
END
But I do have errors:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '>'.
at the expression > 1000.
I don't understand why this does not work.
Bonus: how can we make the name of the server not hard-coded; in PRD, it should be SqlServerPrd, but it seems that OPENQUERY does not accept variables for its arguments...

Invalid STRING_SPLIT args in SQL Server

I am trying to parse a cell that is data type nvarchar(max) like it is csv in SQL Server 2017. I was hoping to use the STRING_SPLIT return a row of data for each value in the array-like string. However, when I run the following code I get an error.
select this_column
into #t
from that_table
where coordinate_x = 1
and coordinate_y = 7
select * from STRING_SPLIT(#t.this_column, ',')
Msg 4104, Level 16, State 1, Line 16
The multi-part identifier "#t.this_column" could not be bound
Msg 8116, Level 16, State 1, Line 16
Argument data type void type is invalid for argument 1 of string_split function
How can I parse this data?
You can't pass a table to a inline table function, you need to include it in your FROM:
SELECT {YourColumns}
FROM #t T
CROSS APPLY STRING_SPLIT(T.this_column, ',') SS;
You'll want to use a cross apply with your temp table
Here's a working example so you can see how that works:
DECLARE #TestData TABLE
(
[TestData] NVARCHAR(MAX)
);
INSERT INTO #TestData (
[TestData]
)
VALUES ( N'1,2,3,4,5,6,7,8,9');
SELECT [b].[value] FROM #TestData [a]
CROSS APPLY[STRING_SPLIT([a].[TestData], ',') [b];
So for your situation, just a small tweak to what you already have, something like:
SELECT [b].[value] FROM #t a
CROSS APPLY STRING_SPLIT(a.this_column,',') b

SQL Server 2012 pivot error

I'm doing a dynamic pivot to create a cross tab with dates. The #Query generated is :-
SELECT [R_Ref]
,CONCAT(datepart(yyyy,[Transaction_Date]), '-', RIGHT('00' + CONVERT(NVARCHAR(2), datepart(M,[Transaction_Date])), 2)) as 'Month'
,[Transaction_Value]
FROM [T-Files].[dbo].[T_Transactions]
as MyTX
PIVOT (
SUM(MyTX.[Transaction_Value])
FOR MyTX.[Month] IN ( [2016-05], [2016-06], [2016-07])
) p
but this generates these errors
Msg 207, Level 16, State 1, Line 9
Invalid column name 'Month'.
Msg 207, Level 16, State 1, Line 3
Invalid column name 'Transaction_Value'.
I can run the top select without the pivot fine, what's wrong in the PIVOT statement?
TIA :o)
You need to put pivot source in sub-select since you are making some manipulation to generate Month.
SELECT *
FROM (SELECT [R_Ref],
Concat(Datepart(yyyy, [Transaction_Date]), '-', RIGHT('00'+ CONVERT(NVARCHAR(2), Datepart(M, [Transaction_Date])), 2)) AS 'Month',
MyTX.[Transaction_Value]
FROM [T-Files].[dbo].[T_Transactions] AS MyTX) A
PIVOT ( Sum([Transaction_Value])
FOR [Month] IN ( [2016-05],
[2016-06],
[2016-07]) ) p

SQL scalar valued function throwing "Invalid Object Name" error

My SQL scalar valued function is defined in the following code:
CREATE FUNCTION CtrAmount ( #Ctr_Id int )
RETURNS MONEY
AS
BEGIN
DECLARE #CtrPrice MONEY
SELECT #CtrPrice = SUM(amount)
FROM Contracts
WHERE contract_id = #Ctr_Id
RETURN(#CtrPrice)
END
GO
SELECT * FROM CtrAmount(345)
GO
But when it comes to the SELECT line, I am getting this error:
Msg 208, Level 16, State 3, Line 14
Invalid object name 'CtrAmount'.
Int(10) - unknown type
CREATE FUNCTION dbo.CtrAmount
(
#Ctr_Id INT
)
RETURNS MONEY
AS
BEGIN
RETURN (
SELECT SUM(amount)
FROM dbo.Contracts
WHERE contract_id = #Ctr_Id
)
END
GO
SELECT dbo.CtrAmount(345)
GO

Issue creating function with a "with"

I am trying to create this function(variable names changed so allow naming mistakes as when tested original without function works fine),
CREATE FUNCTION [dbo].[GetQuality](#FruitID VARCHAR(200))
RETURNS varchar(200)
AS
BEGIN
DECLARE #Result varchar(200)
SET #Result = (
WITH
latest AS
(
SELECT * FROM (SELECT TOP 1 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) a
),
result AS
(
SELECT
latest.ExpiryDate as LatestExpiryDate, latest.Size as LatestSize, latest.Weight as LatestWeight,
previous.ExpiryDate as PreviousExpiryDate, previous.Size as PreviousSize, previous.Weight as PreviousWeight,
CASE SIGN((latest.Weight * latest.Size) - (previous.Weight * previous.Size))
WHEN 1 THEN 'Increased'
WHEN 0 THEN 'Static'
WHEN -1 THEN 'Decreased'
ELSE 'No Previous Data'
END AS Movement
FROM (SELECT TOP 1 * FROM (SELECT TOP 2 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) x ORDER BY ExpiryDate) previous
FULL OUTER JOIN latest ON previous.FruitID = latest.FruitID
)
SELECT result.Movement AS FruitMovement from result;
)
RETURN #Result
END
Error
Msg 156, Level 15, State 1, Procedure GetQuality, Line 10
Incorrect syntax near the keyword 'WITH'.
Msg 319, Level 15, State 1, Procedure GetQuality, Line 10
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Msg 102, Level 15, State 1, Procedure GetQuality, Line 14
Incorrect syntax near ','. Msg 102, Level 15, State 1, Procedure GetQuality, Line 31 Incorrect syntax near ')'.
I think you can move the assignment down, and put a semi colon before the with, and all should be good.
CREATE FUNCTION [dbo].[GetQuality](#FruitID VARCHAR(200))
RETURNS varchar(200)
AS
BEGIN
DECLARE #Result varchar(200);
WITH
latest AS
(
SELECT * FROM (SELECT TOP 1 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) a
),
result AS
(
SELECT
latest.ExpiryDate as LatestExpiryDate, latest.Size as LatestSize, latest.Weight as LatestWeight,
previous.ExpiryDate as PreviousExpiryDate, previous.Size as PreviousSize, previous.Weight as PreviousWeight,
CASE SIGN((latest.Weight * latest.Size) - (previous.Weight * previous.Size))
WHEN 1 THEN 'Increased'
WHEN 0 THEN 'Static'
WHEN -1 THEN 'Decreased'
ELSE 'No Previous Data'
END AS Movement
FROM (SELECT TOP 1 * FROM (SELECT TOP 2 * FROM Fruits_Crate WHERE FruitID like #FruitID ORDER BY ExpiryDate DESC) x ORDER BY ExpiryDate) previous
FULL OUTER JOIN latest ON previous.FruitID = latest.FruitID
)
SELECT #RESULT = result.Movement AS FruitMovement from result;
RETURN #Result
END

Resources