【问题标题】:SQL query to select most recent of duplicatesSQL 查询以选择最近的重复项
【发布时间】:2014-07-24 06:42:21
【问题描述】:

我有一个值表,例如每个条目都存储了一个日期

  • 姓名
  • 年龄
  • 付款金额
  • 日期

谁能帮我写一个查询,只显示特定年龄范围内任何人的最近付款。

例如,如果我有 5 个条目,并且想要所有 20-25 岁的人的最新付款

Allan, 45, $1500, 1/1/2014
Tim, 22, $1500, 1/2/2001
John, 25, $2000, 2/3/2001
Tim, 22, $2500, 1/2/2010
John, 25, $3000, 2/3/2010

它只会返回底部的 2 行

【问题讨论】:

  • 请列出您的尝试。
  • 你实际尝试过什么?
  • 您的表中有 KEY 吗?还是只是名字?

标签: sql


【解决方案1】:

您没有说明您的 DBMS,所以这是 ANSI SQL

select *
from (
  select name, 
         age,
         PaymentAmount,
         Date, 
         row_number() over (partition by name order by date desc) as rn
  from the_table
  where age between 22 and 25
) t
where rn = 1;

另一种选择是使用共同相关的子查询:

select name,age,paymentamount,date 
from the_table t1
where age between 22 and 25 
and date = (select max(date) 
            from the_table t2
             where t2.name = t1.name
               and t2.age between 22 and 25)
order by name;

通常使用窗口函数的解决方案比关联子查询更快,因为只需要对表进行一次访问。

SQLFiddle:http://sqlfiddle.com/#!15/17e37/4

顺便说一句:有一个名为age 的列有点可疑,因为您需要每年更新它。您应该存储出生日期,然后在检索数据时计算年龄。

【讨论】:

    【解决方案2】:

    此查询将为您提供 20 岁和 25 岁的最近付款的所有记录。根据您的数据库语法使用 TOP 2LIMIT 2rownum <=2 限制它

    SELECT NAME,AGE,PAYMENTAMOUNT,DATE FROM MY_TABLE
    WHERE AGE BETWEEN 20 AND 25 
    AND DATE IN 
        (
            SELECT MAX(DATE) 
        FROM MY_TABLE 
        WHERE 
        AGE BETWEEN 20 AND 25
         );
    

    按照 horse_with_no_name 进行编辑:

    SELECT NAME,AGE,PAYMENTAMOUNT,DATE 
    FROM the_table
    WHERE AGE BETWEEN 20 AND 25 
    AND DATE IN 
        (
            SELECT (DATE) 
        FROM the_table
        WHERE 
        AGE BETWEEN 20 AND 25 order by date desc limit 2
         )
    limit 2;
    

    小提琴参考:http://sqlfiddle.com/#!15/17e37/10

    【讨论】:

    • 这不会返回正确的信息:sqlfiddle.com/#!15/17e37/6 您需要一个共同相关的子查询来检索最新的日期每个名字
    • @a_horse_with_no_name:你是对的。我已经修改了没有相关子查询的答案。如果需要,请检查和编辑。感谢您的意见!
    【解决方案3】:

    最简单的,试试下面这个查询
    select name,age,paymentamount,date from yourtablename where date in (select max(date) from yourtablename where age between 20 and 25 and group by name);

    【讨论】:

    • 这行不通,如果在yourtablename 我们还有一个最旧的条目,但他的付款日期是 2001 年 3 月
    • @paubo147 请澄清
    • IN 部分需要一个相关的子查询。您的语句不会根据样本数据返回任何内容,因为max(date) 返回2014-01-01,其中年龄在 22 到 25 之间的行都不满足:sqlfiddle.com/#!15/17e37/2
    • @a_horse_with_no_name 我已编辑,告诉是否还有问题
    • age between 20 and 25 添加到子查询中
    【解决方案4】:

    您应该创建一个带有标识列的表以使您的生活更轻松

    • ColumnPrimaryKey IDENTITY (1,1)
    • 姓名
    • 年龄
    • 付款金额
    • 日期

    SELECT TOP 2 * FROM [TableName] Where Age BETWEEN 20 AND 25 ORDER BY [PrimaryKey] DESC

    上面的查询将返回表中插入的前两行

    【讨论】:

      【解决方案5】:

      你可以在like之间使用

      select * from meta where title='$title' and (date between '$start_date' and '$end_date').
      

      【讨论】:

        猜你喜欢
        • 2012-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-28
        • 2014-09-02
        • 1970-01-01
        • 1970-01-01
        • 2016-07-24
        相关资源
        最近更新 更多