SQL 新手,经验丰富的 VBA-er 需要一些帮助。
我对需要获得特定类型的一些不同费用的交易有看法。费用在表格中,其中一些字段是必需的,而其他字段可能为 NULL。通过这种方式,我们可以获得一个通用的费用结构,并且仍然允许特定的特价。
我现在的目标是找到最佳匹配费用。这是以下费用:
- 符合所有要求的标准,
- 匹配所有可选条件或
NULL
为它们提供, - 具有通过 1. 和 2 的所有费用中最匹配的可选标准。
现在我得到了这个代码的一个版本,但作为一个过程。但是,由于我需要在视图中使用它,因此我无法使用该版本,并且函数中不允许使用临时表)。
在查看了这个论坛和其他人之后,我得出一个仍然给出 2 个错误的结果:
1. ErrorMessage: Incorrect syntax near '@tblTEMP'
,
2. ErrorMessage: Incorrect syntax near 'BEGIN'
。
我当前的脚本如下(使用局部变量表):
ALTER FUNCTION [dbo].[fnStandardFeeBAK]
(@Type_Id BIGINT, @Party_Id BIGINT, @I_A_Id BIGINT, @Grid_Id BIGINT,
@Market_Id BIGINT, @Counterparty_Id BIGINT, @Product_Id BIGINT,
@DealDate DATETIME)
RETURNS TABLE
AS
BEGIN
DECLARE @tblTEMP TABLE (Standard_Fee DECIMAL(38,8), Currency VARCHAR(50),
Unit VARCHAR(50), Unit2 VARCHAR(50), MatchScore BIGINT);
WITH @tblTEMP AS
(SELECT Standard_Fee, V2.Element AS Currency, V1.Element AS Unit,
V2.Element+'/'+V1.Element AS Unit2,
SF.I_A_Id, SF.Grid_Id, SF.Product_Id, SF.Counterparty_Id,
(CASE WHEN SF.I_A_Id = @I_A_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Grid_Id = @Grid_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Product_Id = @Product_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Counterparty_Id = @Counterparty_Id THEN 1 ELSE 0 END)
AS MatchScore
FROM tblStandard_Fee AS SF
LEFT JOIN tblElement AS V1 ON V1.Element_Id = SF.Unit_Id
LEFT JOIN tblElement AS V2 ON V2.Element_Id = SF.Currency_Id
WHERE SF.Type_Id = @Type_Id AND SF.Party_Id = @Party_Id AND
SF.Market_Id = @Market_Id
AND SF.Date_From < @DealDate
AND (SF.Date_To > @DealDate OR SF.Date_To IS NULL)
AND (SF.I_A_Id = @I_A_Id OR SF.I_A_Id IS NULL)
AND (SF.Grid_Id = @Grid_Id OR SF.Grid_Id IS NULL)
AND (SF.Product_Id = @Product_Id OR SF.Product_Id IS NULL)
AND (SF.Counterparty_Id = @Counterparty_Id OR SF.Counterparty_Id IS NULL))
RETURN
SELECT Standard_Fee, Currency, Unit, Unit2
FROM @tblTEMP
WHERE MatchScore= MAX(MatchScore)
END
如果不让我知道,我希望我的问题很清楚。
感谢您提出建议,甚至用最后一点解决我的问题!
所以 LittleBobbyTables 的所有帮助结合起来给了我一个工作的最终结果。请不要忘记给他学分。
工作代码:
ALTER FUNCTION [dbo].[fnStandardFeeBAK]
(@Type_Id BIGINT, @Party_Id BIGINT, @I_A_Id BIGINT, @Grid_Id BIGINT,
@Market_Id BIGINT, @Counterparty_Id BIGINT, @Product_Id BIGINT, @DealDate DATETIME)
RETURNS @YourTable TABLE
(
-- Columns returned by the function
Standard_Fee DECIMAL(38,8),
Currency VARCHAR(50),
Unit VARCHAR(50),
Unit2 VARCHAR(50)
)
AS
BEGIN
WITH YourCTE(Standard_Fee, Currency, Unit, Unit2, MatchScore) AS
(
SELECT Standard_Fee, V2.Element AS Currency, V1.Element AS Unit,
V2.Element + '/' + V1.Element AS Unit2,
(CASE WHEN SF.I_A_Id = @I_A_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Grid_Id = @Grid_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Product_Id = @Product_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Counterparty_Id = @Counterparty_Id THEN 1 ELSE 0 END)
AS MatchScore
FROM tblStandard_Fee AS SF
LEFT JOIN tblElement AS V1 ON V1.Element_Id = SF.Unit_Id
LEFT JOIN tblElement AS V2 ON V2.Element_Id = SF.Currency_Id
--Type_ID, Party_ID and Market_Id are always present, others can have NULL values
WHERE SF.Type_Id = @Type_Id AND SF.Party_Id = @Party_Id
AND SF.Market_Id = @Market_Id AND SF.Date_From < @DealDate
AND (SF.Date_To > @DealDate OR SF.Date_To IS NULL)
AND (SF.I_A_Id = @I_A_Id OR SF.I_A_Id IS NULL)
AND (SF.Grid_Id = @Grid_Id OR SF.Grid_Id IS NULL)
AND (SF.Product_Id = @Product_Id OR SF.Product_Id IS NULL)
AND (SF.Counterparty_Id = @Counterparty_Id OR SF.Counterparty_Id IS NULL)
GROUP BY Standard_Fee, V1.Element, V2.Element, SF.I_A_Id, SF.Grid_Id, SF.Product_Id, SF.Counterparty_Id
)
INSERT @YourTable
SELECT Standard_Fee, Currency, Unit, Unit2
FROM YourCTE
GROUP BY MatchScore, Standard_Fee, Currency, Unit, Unit2
HAVING MatchScore = (SELECT MAX(MatchScore) FROM YourCTE)
RETURN;
END