【问题标题】:SQL Query in looking at first two records of a tableSQL 查询查看表的前两条记录
【发布时间】:2014-11-28 21:19:42
【问题描述】:

我有一个员工表,用于记录工资/费率历史记录。好像……

员工# EffectDate Salary 00016 2014-01-03 78100.00 00016 2013-07-03 75130.00 00016 2013-01-06 72140.00 00114 2014-07-15 85610.00 00244 2014-01-10 54130.00 00244 2013-06-30 50140.00 00634 2013-12-25 72560.00 00634 2013-04-05 69348.00 00634 2012-01-01 64530.00

我正在尝试为员工获取一行,显示当前薪水、最后生效日期和最近的最后薪水...

员工# CurrentSalary LastChange PreviousSalary 00016 78100.00 2014-01-03 75130.00 00114 85610.00 2014-07-15 空 00244 54130.00 2014-01-10 50140.00 00634 72560.00 2013-12-25 69348.00

使用 Microsoft SQL 2012

【问题讨论】:

  • 您要求我们为您编写 SQL 查询吗?
  • 你试过什么代码? SO 不是代码外包社区。​​span>
  • 你为什么反对聚合(根据你的 cmets)?多个相关子查询肯定比单个聚合子查询慢。

标签: sql sql-server-2012


【解决方案1】:

我脑海中的快速变体:

select
    t.Employee,
    (select top 1 Salary
        from table as a
        where a.Employee = t.Employee and a.EffectDate = t.LastChange
        order by EffectDate desc) as CurrentSalary,
    t.LastChange,
    (select top 1 Salary
        from table as a
        where a.Employee = t.Employee and a.EffectDate < t.LastChange
        order by EffectDate desc) as PreviousSalary
from (
    select Employee, max(EffectDate) as LastChange
    from table
    group by Employee) as t

【讨论】:

  • 谢谢。简单并且必须在我当前的 SQL 查询中对表进行分区。带有 AND 子句的 Select Top 1 是我出错的地方。再次感谢!
【解决方案2】:

这是使用row_numbermaxcase(一种旋转形式)的一种方式:

with cte as (
  select *,
    row_number() over (partition by employeenum order by effectdate desc) rn
  from salary
  )
select employeenum,
  max(case when rn = 1 then salary end) currentsalary,
  max(case when rn = 1 then effectdate end) lastchange,
  max(case when rn = 2 then salary end) previoussalary
from cte
group by employeenum

【讨论】:

    【解决方案3】:

    试试这个,使用CTE,你可以通过分区得到ROW_NUMBER(),然后在查询中使用这个行号。

    DECLARE @tbl TABLE (
        EmployeeId    VARCHAR (20)  ,
        EffectiveDate DATE          ,
        salary        DECIMAL (8, 2));
    
    INSERT  INTO @tbl (EmployeeId, EffectiveDate, salary)
    VALUES           (00016, getdate(), 7852.00);
    
    INSERT  INTO @tbl (EmployeeId, EffectiveDate, salary)
    VALUES           (00016, getdate() + 1, 7952.00);
    
    INSERT  INTO @tbl (EmployeeId, EffectiveDate, salary)
    VALUES           (00016, getdate() + 2, 8052.00);
    
    INSERT  INTO @tbl (EmployeeId, EffectiveDate, salary)
    VALUES           (00017, getdate(), 7852.00);
    
    INSERT  INTO @tbl (EmployeeId, EffectiveDate, salary)
    VALUES           (00017, getdate() + 1, 7952.00);
    
    INSERT  INTO @tbl (EmployeeId, EffectiveDate, salary)
    VALUES           (00018, getdate(), 7852.00);
    
    WITH   cteSalary
    AS     (SELECT EmployeeId,
                   EffectiveDate,
                   salary,
                   ROW_NUMBER() OVER (PARTITION BY EmployeeId 
                                  ORDER BY EffectiveDate DESC) AS rn
            FROM   @tbl)
    SELECT a.EmployeeId,
           a.EffectiveDate,
           a.salary,
           b.salary AS 'Previous salary'
    FROM   cteSalary AS a
           LEFT OUTER JOIN
           cteSalary AS b
           ON a.EmployeeId = b.EmployeeId
              AND b.rn = 2
    WHERE  a.rn = 1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      相关资源
      最近更新 更多