1

SQL は初めてで、ベテランの VBA 担当者で、支援が必要です。

特定の種類のいくつかの異なる料金を取得する必要があるトランザクションに関するビューがあります。料金は、一部のフィールドが必須であり、他のフィールドが NULL である可能性があるテーブルにあります。このようにして、一般的な料金体系を設定し、特定のスペシャルを許可することができます.

今の私の目標は、最適なマッチング手数料を見つけることです。これは次の料金です。

  1. 必要なすべての基準に一致し、
  2. すべてのオプションの基準に一致するか、またはNULLそれらに対して持っています。
  3. 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
4

1 に答える 1

2

表値のユーザー定義関数のドキュメントを参照してください。正しい構文は次のとおりです。

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

そして最後に:

    INSERT @YourTable 
    SELECT Standard_Fee, Currency, Unit, Unit2
    FROM YourCTE
    WHERE MatchScore= MAX(MatchScore)
    RETURN;
END;

編集:CTEを台無しにした、あなたは一時的なテーブルを必要としません。

それをすべて一緒に投げると、次のようになります。

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,
  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))

  INSERT @YourTable 
    SELECT Standard_Fee, Currency, Unit, Unit2
    FROM YourCTE
    WHERE MatchScore= MAX(MatchScore)
  RETURN;
END;
于 2012-08-08T13:28:28.000 に答える