sql-server-2008 - 使用字段的MAX选择记录返回表的MAX忽略条件

标签 sql-server-2008 tsql stored-procedures cursor max

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

很抱歉,如果这让您感到困惑,我会尽力解释

报告需要为每个供应商注册一份供应 Assets list 、 Assets 描述、当前位置、价格以及 Assets 仍需折旧的金额。

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

如果能告诉我我做错了什么(可能有很多)以及如何解决它,我将非常感激,在此先感谢您。

最佳答案

通过 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 确保了这一点。

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

关于sql-server-2008 - 使用字段的MAX选择记录返回表的MAX忽略条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15965891/

相关文章:

mysql - 给定一个日期,在 MySQL 非线性中查找上一个和/或当前和下一个 x# 日期

sql-server-2008 - 获取该月指定周的开始日期和结束日期

sql-server - 如何使用希伯来语传递 SQL 存储过程 NVARCHAR 参数?

sql - 如何使用 TSQL 从字符串中提取数字

sql-server - sql中NULL的数学运算

java - 执行存储过程时调用异常时获取错误数量或类型的参数

c# - 在 GridView 数据集中格式化 DateTime 字符串表示

sql-server-2008 - 如何在t-sql中读取xml?

sql-server - 重复 SQL 查询并创建一个输出列

sql - 在 SQL 中,如何将位掩码总计中的值拆分为逗号分隔的字符串