3

我正在为报告做一个存储过程,我试图只获取那些具有确定字段(累计金额)的最高值的记录,问题是我似乎找不到解决方案,我想出的唯一解决方案是使用额外条件,问题是每个月(期间)字段都会更改并且并非所有记录都更新但我需要全部检索它们......(如果资产在那里折旧将不再是该表中与该资产相关的记录)

很抱歉,如果这令人困惑,我会尽力解释

该报告需要为每个供应商登记一份供应资产清单、描述、当前位置、价格以及资产还需要折旧多少。

所以,我正在做的是首先获取供应商列表,然后获取与位置相关的资产列表(使用光标)然后我尝试计算需要折旧的金额,有一个名为“DEPRECIACIONES”的表存储资产、期间以及每个期间和尚未完全折旧的每项资产从该资产中折旧的金额。当我尝试计算资产折旧的 MAX 金额,然后选择具有该 MAX 金额的项目的行时,问题就出现了,我确定我做错了什么,我的 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。

WHERE 子句a.Activo IS NOT NULL不是必需的,因为 INNER JOIN 确保了它。

希望这可以帮助您解决问题。

于 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 回答