在交替行上使用缺少 PK 的 LAG/LEAD
Using LAG/LEAD with missing PK on alternate rows
我正在尝试在 SQL Server 2012 中使用以下 table:
EMPID JOB_TITLE SALARY
------------------------------------
1234 SALES 56000
NULL NULL 54000
1235 MARKETING 72000
NULL NULL 71000
table 源自 excel 提取,为此我使用 OPENROWSET 导入。
我需要导出“先前的”薪水值,您可以假设它始终以 table 中的自然顺序存在于以下记录中,并将其显示为新列。
预期输出:
EMPID JOBTITLE SALARY PREV_SALARY
--------------------------------------------------
1234 BUSINESS ANALYST 56000 54000
1235 SALES MANAGER 72000 71000
显然,有点挑战,因为下一行没有主键,如果我不能识别用来“分区”记录的值,我就不能准确地使用 LEAD 函数。有什么想法吗?
我添加了相同的内容 values/code:
INSERT INTO #EMP
VALUES (1234, 'Sales', 56000),
(NULL, NULL, 54000),
(1235, 'Marketing', 72000),
(NULL, NULL, 70500)
SELECT
EMPID,
JOBTITLE,
SAL,
LEAD(SAL,1,0) OVER (ORDER BY NEWID()) AS PREV_SAL
FROM
#EMP
WHERE
EMPID IS NOT NULL
如果没有定义行排序的列,则问题无法解决 - SQL table 的行 未排序 设计.
如果你有一个排序栏,你可以这样做:
select *
from (
select e.*, lead(salary) over(order by id) as prev_salary
from employee e
) t
where empid is not null
这假定非空行和空行始终正确交错。如果不是这种情况,那么我会推荐一些间隙和岛屿技术,如:
select max(empid) as empid,
max(case when rn = 1 then job_title end) as job_title,
max(case when rn = 1 then salary end) as salary,
max(case when rn = 2 then salary end) as prev_salary
from (
select e.*, row_number() over(partition by grp order by empid) rn
from (
select e.*, count(empid) over(order by id) as grp
from employee e
) t
) t
group by grp
根据@Honeybadger的建议,我在创建临时登陆的时候实现了IDENTITY(1,1)属性table。这在我加载数据时捕获了自然行序列。很有魅力!
CREATE TABLE #EMP
(
EMPID INT
, JOBTITLE NVARCHAR(19)
, SAL INT
, ROW_SEQ INT IDENTITY(1,1)
)
INSERT INTO #EMP
VALUES (1234, 'Sales', 56000),
(NULL, NULL, 54000),
(1235, 'Marketing', 72000),
(NULL, NULL, 70500)
SELECT * FROM (
SELECT
EMPID,
JOBTITLE,
SAL,
LEAD(SAL,1,0) OVER (ORDER BY ROW_SEQ ) AS PREV_SAL
FROM #EMP ) T WHERE EMPID IS NOT NULL
输出:
EMPID JOBTITLE SAL PREV_SAL
1234 Sales 56000 54000
1235 Marketing 72000 70500
我正在尝试在 SQL Server 2012 中使用以下 table:
EMPID JOB_TITLE SALARY
------------------------------------
1234 SALES 56000
NULL NULL 54000
1235 MARKETING 72000
NULL NULL 71000
table 源自 excel 提取,为此我使用 OPENROWSET 导入。
我需要导出“先前的”薪水值,您可以假设它始终以 table 中的自然顺序存在于以下记录中,并将其显示为新列。
预期输出:
EMPID JOBTITLE SALARY PREV_SALARY
--------------------------------------------------
1234 BUSINESS ANALYST 56000 54000
1235 SALES MANAGER 72000 71000
显然,有点挑战,因为下一行没有主键,如果我不能识别用来“分区”记录的值,我就不能准确地使用 LEAD 函数。有什么想法吗?
我添加了相同的内容 values/code:
INSERT INTO #EMP
VALUES (1234, 'Sales', 56000),
(NULL, NULL, 54000),
(1235, 'Marketing', 72000),
(NULL, NULL, 70500)
SELECT
EMPID,
JOBTITLE,
SAL,
LEAD(SAL,1,0) OVER (ORDER BY NEWID()) AS PREV_SAL
FROM
#EMP
WHERE
EMPID IS NOT NULL
如果没有定义行排序的列,则问题无法解决 - SQL table 的行 未排序 设计.
如果你有一个排序栏,你可以这样做:
select *
from (
select e.*, lead(salary) over(order by id) as prev_salary
from employee e
) t
where empid is not null
这假定非空行和空行始终正确交错。如果不是这种情况,那么我会推荐一些间隙和岛屿技术,如:
select max(empid) as empid,
max(case when rn = 1 then job_title end) as job_title,
max(case when rn = 1 then salary end) as salary,
max(case when rn = 2 then salary end) as prev_salary
from (
select e.*, row_number() over(partition by grp order by empid) rn
from (
select e.*, count(empid) over(order by id) as grp
from employee e
) t
) t
group by grp
根据@Honeybadger的建议,我在创建临时登陆的时候实现了IDENTITY(1,1)属性table。这在我加载数据时捕获了自然行序列。很有魅力!
CREATE TABLE #EMP
(
EMPID INT
, JOBTITLE NVARCHAR(19)
, SAL INT
, ROW_SEQ INT IDENTITY(1,1)
)
INSERT INTO #EMP
VALUES (1234, 'Sales', 56000),
(NULL, NULL, 54000),
(1235, 'Marketing', 72000),
(NULL, NULL, 70500)
SELECT * FROM (
SELECT
EMPID,
JOBTITLE,
SAL,
LEAD(SAL,1,0) OVER (ORDER BY ROW_SEQ ) AS PREV_SAL
FROM #EMP ) T WHERE EMPID IS NOT NULL
输出:
EMPID JOBTITLE SAL PREV_SAL
1234 Sales 56000 54000
1235 Marketing 72000 70500