3

レポートのストアド プロシージャを実行していて、決定されたフィールド (累積量) の値が最も高いレコードのみを取得しようとしていますが、これに対する解決策を見つけることができないようです。私が思いついた唯一の解決策は、追加の条件を使用することです。問題は、フィールドが毎月 (期間) 変更され、すべてのレコードが更新されるわけではありませんが、すべてを取得する必要があることです... (資産が減価償却されている場合)そのテーブル内のその資産に関連するレコードはもうありません)

分かりにくくてすみません、頑張って説明します

レポートには、登録されたサプライヤーごとに、提供する資産、その説明、現在の場所、価格、および資産から減価償却する必要がある金額のリストが必要です。

だから、私がやっていることは、最初にサプライヤーのリストを取得し、次に場所に関連付けられた資産のリストを取得して (カーソルを使用して)、減価償却する必要がある金額を計算しようとしています。「DEPRECIACIONES」というテーブルがあります。資産、期間、および各期間と完全に減価償却されていない各資産について、その資産から減価償却された金額を保存します。問題は、資産の減価償却の最大金額を計算しようとして、その最大金額を持つアイテムの行を選択しようとすると発生します。何か間違ったことをしていると確信しています。TSQL と一般的なデータベースの知識はありません。私は独学で学ぼうとしています。

ここに間違った出力をスローするスキーマ、テーブル、およびストアド プロシージャをアップロードしました。

http://sqlfiddle.com/#!3/78c32

右の出力は次のようになります。

Proveedor | Activo | Descripcion | Ubicacion Actual | Costo Adquisicion | Saldo sin depreciar | Periodo

Supplier | Asset | Description | Current Location | Cost | Money to be depreciated | Period
-------------------------------------------------------------------------------------------
Monse    |ActivoT|  texthere   |       1114       |2034.50|    RANDOM NUMBER HERE  |RandomP
Monse    |cesart |  texthere   |       4453       |4553.50|    RANDOM NUMBER HERE  |RandomP
nowlast  | activ |  texthere   |       4453       |1234.65|    RANDOM NUMBER HERE  |RandomP
nowlast  |augusto|  texthere   |       4450       |4553.50|    RANDOM NUMBER HERE  |RandomP
Sara     |Activo |  texthere   |       1206       |746.65 |    RANDOM NUMBER HERE  |RandomP

私が間違っていること(おそらく多くのことです)とそれを修正する方法を教えていただければ幸いです。よろしくお願いします。

4

2 に答える 2

1

SqlFiddle を介して完全な情報を提供する優れたスキル。

完全な答えはありませんが、これが役立つかもしれません。

まず、カーソルを捨ててください - デバッグが難しく、遅くなる可能性があります。SELECT ステートメントにリファクタリングします。これは私の試みであり、あなたのコードと論理的に同等である必要があります:

SELECT 
  p.Proveedor,
  a.Activo, 
  a.Descripcion, 
  Ubi.Ubicacion, 
  saldo_sin_depreciar = a.Costo_adquisicion - d.Monto_acumulado,
  d.Periodo

FROM  
  PROVEEDORES p
    INNER JOIN ACTIVOS_FIJOS a  ON a.Proveedor = p.Proveedor
    INNER JOIN DEPRECIACIONES d ON a.Activo = d.Activo 
    INNER JOIN 
      (
        SELECT 
         MAX(d1.Monto_acumulado) AS MaxMonto 
        FROM  DEPRECIACIONES d1 
         INNER JOIN  DEPRECIACIONES d2 
           ON d1.Monto_acumulado = d2.Monto_acumulado
      ) MaxAe 
    ON d.Monto_acumulado = MaxAe.MaxMonto

    INNER JOIN ACTIVO_UBICACION Ubi ON a.activo = ubi.activo
    INNER JOIN   
      (
        SELECT 
         activo, 
         ubicacion, 
         Fecha_Ubicacion, 
         RowNum  = row_number() OVER ( partition BY activo ORDER BY abs(datediff(dd, Fecha_Ubicacion, getdate())))
        FROM  
          ACTIVO_UBICACION
      ) UbU 
    ON UbU.ubicacion = Ubi.Ubicacion 

WHERE 
    -- a.Activo IS NOT NULL AND
        UbU.RowNum = 1 

ORDER BY
  p.Proveedor

コメント

結合を定義している WHERE 基準をテーブル リストの ON 句に移動しました。これにより、テーブルを結合する方法を簡単に確認できます。

すべての結合は INNER であることに注意してください。これはあなたが望むものではないかもしれません - あなたはいくつかの LEFT JOIN を必要とするかもしれません、私は言うのに十分なロジックを理解していません。

また、カーソル プロシージャでは、Ubi と UbU の部分が残りのテーブルと明示的に結合していないように見えるため、activo 列に INNER JOIN を鉛筆で書きました。 FK関係。

カーソル コードでは、CROSS JOIN が効果的に取得されますが、これはおそらく間違っており、実行コストも高くなります。

a.Activo IS NOT NULLINNER JOIN によって保証されるため、WHERE 句は必要ありません。

これが整理に役立つことを願っています。

于 2013-04-12T12:31:01.843 に答える
0

カーソルに別のクエリを使用することになり、問題を修正しました。おそらく最適ではありませんが、機能します。データベース関連のことを学ぶたびに、それを最適化します。

新しいクエリは次のとおりです。

DECLARE P CURSOR STATIC
      FOR SELECT a.Proveedor, actub.activo, actub.ubicacion FROM [SISACT].PROVEEDORES p,[SISACT].ACTIVOS_FIJOS a, (SELECT activo, ubicacion, Fecha_Ubicacion, row_number() OVER (
            partition BY activo ORDER BY abs(datediff(dd, Fecha_Ubicacion, getdate()))
          ) AS RowNum FROM [SISACT].ACTIVO_UBICACION) actub WHERE RowNum = 1 AND a.Proveedor = p.Proveedor AND actub.activo = a.Activo
      OPEN P
      FETCH NEXT FROM P INTO @p, @a, @u
                 WHILE @@FETCH_STATUS = 0
                   BEGIN 
             SELECT @activo = a.Activo, @descripcion = a.Descripcion, @costo_adquisicion = a.Costo_adquisicion, @saldo_depreciado = MaxAe.MaxMonto, @periodo = d.Periodo
                FROM [SISACT].ACTIVOS_FIJOS a, [SISACT].DEPRECIACIONES d, SISACT.PROVEEDORES pro, SISACT.ACTIVO_UBICACION actu, (SELECT MAX(d1.Monto_acumulado) AS MaxMonto FROM [SISACT].DEPRECIACIONES d1 INNER JOIN [SISACT].DEPRECIACIONES d2 ON d1.Monto_acumulado = d2.Monto_acumulado WHERE d1.Activo = @a AND d2.Activo = @a) MaxAe
                WHERE a.Activo = d.Activo AND a.Activo = @a AND d.Activo = @a AND a.Proveedor = @p AND actu.Activo = @a AND actu.Ubicacion = @u
                SET @saldo_sin_depreciar = @costo_adquisicion - @saldo_depreciado
FETCH NEXT FROM P INTO @p, @a, @u
                     END
      CLOSE P
      DEALLOCATE P
于 2013-04-13T05:03:05.367 に答える