Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 获取以前的帐户金额?_Sql_Sql Server - Fatal编程技术网

Sql 获取以前的帐户金额?

Sql 获取以前的帐户金额?,sql,sql-server,Sql,Sql Server,我有一张这样的桌子: =============================== | ID | Salary | Date | =============================== | A1 | $1000 | 2020-01-03| ------------------------------- | A1 | $1300 | 2020-02-03| ------------------------------- | A1 | $1500

我有一张这样的桌子:

===============================
|  ID  |  Salary  |    Date   |
===============================
|  A1  |  $1000   | 2020-01-03|
-------------------------------
|  A1  |  $1300   | 2020-02-03|
-------------------------------
|  A1  |  $1500   | 2020-03-01|
-------------------------------
|  A2  |  $1300   | 2020-01-13|
-------------------------------
|  A2  |  $1500   | 2020-02-11|
-------------------------------
预期产出:

==================================================
|  ID  |  Salary  |  Previous Salary |    Date   |
==================================================
|  A1  |  $1500   |       $1300      | 2020-03-01|
--------------------------------------------------
|  A2  |  $1500   |       $1300      | 2020-02-03|
--------------------------------------------------

如何查询始终获取他们以前的工资并显示在另一列/表中?

此查询适用于您

select *, LAG(salary) OVER (partition by id ORDER BY id) as previous from A 

试试这个:假设:表名“PAYROLL”在“PLS”模式中

SELECT R1.ID,R1.SALARY AS SALARY,R2.SALARY AS PREVIOUS_SALARY
FROM PLS.PAYROLL R1
LEFT OUTER JOIN PLS.PAYROLL R2 ON R1.ID=R2.ID AND R2.SALARY_DATE = (SELECT MAX(SALARY_DATE) FROM PLS.PAYROLL WHERE ID=R1.ID AND SALARY_DATE<R1.SALARY_DATE)
WHERE R1.SALARY_DATE=(SELECT MAX(SALARY_DATE) FROM PLS.PAYROLL WHERE ID=R1.ID)
ORDER BY R1.ID

在SQL Server中,可以使用引用指定数据窗口内分区集中上一条记录中的字段


with [Data] as
(
    SELECT ID, Salary, Cast([Date] as Date) [Date]
    FROM (VALUES 
      ('A1', 1000, '2020-01-03'),
      ('A1',1300,'2020-02-03'),
      ('A1',1500,'2020-03-01'),
      ('A2',1300,'2020-01-13'),
      ('A2',1500,'2020-02-11')
    ) as t(ID,Salary,Date)
)
-- above is a simple demo dataset definition, your actual query is below

SELECT ID, Salary, LAG(Salary, 1) 
OVER (
    PARTITION BY [ID]
    ORDER BY [Date]
) as [Previous_Salary], [Date]
FROM [Data] 
ORDER BY [Data].[Date] DESC

生成以下输出:

ID   Salary      Previous_Salary Date
---- ----------- --------------- ----------
A1   1500        1300            2020-03-01
A2   1500        1300            2020-02-11
A1   1300        1000            2020-02-03
A2   1300        NULL            2020-01-13
A1   1000        NULL            2020-01-03

(5 rows affected)
尝试排序,注意在窗口中我们使用升序,在显示中,我们可以显示降序

窗口函数在当前查询之外创建一个虚拟数据集,可以将窗口函数视为并行执行相关查询并在结果中合并的一种方式

在许多简单的实现中,像这样的窗口函数应该提供更好或相同的性能,就像将自己的逻辑写入自连接或子查询一样,例如,这是一个使用交叉应用的等价查询

LAG语法需要更少的代码,明确定义您的意图,并允许基于集合的执行和优化

其他联接样式查询仍将阻止查询,因为它们将要求通过强制以相反顺序加载整个数据集来反转原始数据集,因此不会提供真正基于集或最佳方法


SQL Server开发人员意识到对这些类型的查询有着真正的需求,一般来说,当我们使用自己的设备创建低效的查找查询时,窗口函数旨在为这些类型的分析查询提供最佳实践解决方案。

您可以使用窗口函数和pivot来实现这一点

DECLARE @SampleData TABLE (ID  VARCHAR(5),  Salary MONEY    ,[Date]  DATE)
INSERT INTO @SampleData VALUES
('A1', $1000 , '2020-01-03'),
('A1', $1300 , '2020-02-03'),
('A1', $1500 , '2020-03-01'),
('A2', $1300 , '2020-01-13'),
('A2', $1500 , '2020-02-11')

SELECT ID, [1] Salary, [2] [Previous Salary], [Date]  
FROM (SELECT ID, Salary, MAX([Date]) OVER(PARTITION BY ID) AS [Date], 
        ROW_NUMBER() OVER(PARTITION BY ID ORDER BY [Date] DESC) RN 
     FROM @SampleData ) SRC
PIVOT(MAX(Salary) FOR RN IN ([1],[2])) PVT
ORDER BY ID
结果:

ID    Salary                Previous Salary       Date
----- --------------------- --------------------- ----------
A1    1500,00               1300,00               2020-03-01
A2    1500,00               1300,00               2020-02-11
您可以结合使用和windows函数来查找每个id的上一次薪资,并返回其上一次和上一次薪资

with cte as (
  select id, salary,
         row_number() over (partition by id order by date desc) as position,
         lag(salary) over (partition by id order by date) as previous,
         date
  from payroll
)  
select id, salary, previous, date
from cte 
where position = 1 -- It's the first one because we ordered by date descendingly
结果:

ID    Salary                Previous              Date
----- --------------------- --------------------- ----------
A1    1500,00               1300,00               2020-03-01
A2    1500,00               1300,00               2020-02-11

在线示例:

请说明他们以前的工资是如何计算的。不需要计算。这只是我随机编的一个示例数据。您可以查找滞后分析函数。因此,您的查询将返回5行而不是2行?按ID排序,日期会更合适。若表中包含ID A1的过去一年的工资记录,那个么上面的查询将显示以前工资的每一条记录,我认为这些记录并没有被询问过。请尝试我在答案中写的查询。@marc guillot有一个很好的例子,它使用“行数”窗口函数将结果限制为只显示最新记录(如果需要)
ID    Salary                Previous              Date
----- --------------------- --------------------- ----------
A1    1500,00               1300,00               2020-03-01
A2    1500,00               1300,00               2020-02-11