【问题标题】:Subquery: how to retrieve the last non-zero value from a column?子查询:如何从列中检索最后一个非零值?
【发布时间】:2011-09-16 15:40:59
【问题描述】:

考虑一个包含 3 列的表 customerBalance:名称、日期和余额。假设一组记录如下:

cus_name    cus_date    cus_balance
John        06/14/2011  1000
John        06/15/2011   500
John        06/16/2011     0
Mary        06/14/2011  3000
Mary        06/15/2011  2800
Mary        06/16/2011     0

如何创建一个 SQL 查询,对于日期 6/16/2011 而不是 0,返回基于日期的最后一个非零值(在示例中,John 为 500 美元,Mary 为 2800 美元)?

我正在尝试使用子查询来执行此操作,该子查询使用 Max 函数来检索具有非零值的最后日期,但我没有成功。这个例子很“荒谬”,但我确实需要在我的数据集中做这样的操作。谢谢!

【问题讨论】:

  • 如果您在 6 月 17 日为 Mary 获得 1000 分怎么办?还是将日期作为参数?请问还有什么数据库/版本?

标签: sql


【解决方案1】:

注意:如果您可以指定数据库和版本,则可以改进此查询。

试试这个:

SELECT *
  FROM customers
 WHERE (cus_name, cus_date) 
        IN 
        (
            SELECT cus_name, MAX(cus_date)
              FROM customers
             WHERE cus_balance <> 0
             GROUP BY cus_name
        )

更新:替代版本:

SELECT a.*
    FROM customers a,
            (
                SELECT cus_name, MAX(cus_date)
                    FROM customers
                 WHERE cus_balance <> 0
                 GROUP BY cus_name
            ) b
 WHERE a.cus_name = b.cus_name
   AND a.cus_date = b.cus_date

【讨论】:

  • 它看起来很棒,但不幸的是我使用的是“古老的”Access 2000,语法不能正常工作。你有其他方法吗?
  • @darth:我在帖子中添加了一个替代版本(虽然没有测试)。请尝试一下..
  • 在询问之前我正在做类似您的第二个版本的操作,并且我从 Access 收到了与我实现您的代码时相同的错误消息,这应该是英文的类似内容:“你做了一个子查询可以在主查询的 FROM 子句中不使用保留字 EXISTS 的情况下返回多个字段。检查子查询中的 SELECT 指令,使其只需要一个字段”。很无聊,但我还没有解决它。
  • @darth:我在 Access 2007 中运行了第二个查询,它运行良好。我收到了你提到的第一个版本的错误?你能检查一下吗
  • 工作正常。我做了一些调整,因为我的表架构比这个例子复杂一点,而且我使用“First”语句从子查询中选择“Balance”值。非常感谢您的帮助。
【解决方案2】:

这里是:

CREATE Table #temp
(
    Cus_Name VARCHAR(200) NULL,
    Cus_Date Char(8) NULL,
    Cus_Balance INT NULL
)

INSERT INTO #temp VALUES ('John' , '20110614' ,1000 )
INSERT INTO #temp VALUES ('John' , '20110615' , 500 )
INSERT INTO #temp VALUES ('John' , '20110616' ,   0 )
INSERT INTO #temp VALUES ('Mary' , '20110614' ,3000 )
INSERT INTO #temp VALUES ('Mary' , '20110615' ,2800 )
INSERT INTO #temp VALUES ('Mary' , '20110616' ,   0 )

SELECT 
    T.Cus_Name ,
    MIN(t.Cus_Balance)
FROM #temp t 
WHERE t.Cus_Balance <>0
GROUP BY t.Cus_Name

DROP TABLE #temp

【讨论】:

  • 感谢@Raj Jayaswal 的回复,但我不能像我的情况那样对超过一百万条记录使用这种方法。问候。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多