使用 ROW_NUMBER() window 函数选择行
Selecting row with ROW_NUMBER() window function
我目前正在为工作中的流程编写查询。我试图通过应用 ROW_NUMBER() 函数来获取特定行,然后根据行定位选择行。但是,我得到以下 error:
SQL compilation error: Window function [ROW_NUMBER() OVER (ORDER BY EMPLOYEE.SALARY_GRADE_ID ASC
NULLS LAST)] appears outside of SELECT, QUALIFY, and ORDER BY clauses.
查询:
SELECT Employee.Salary_Grade_Id, SUM(Salary_Grades.Grade_Amount) AS total, ROW_NUMBER() OVER(ORDER
BY Employee.Salary_Grade_Id) AS rowCol FROM Employee, Salary_Grades
WHERE (Employee.Salary_Grade_Id = Salary_Grades.Grade_Id AND rowCol = 1) GROUP BY
Employee.Salary_Grade_Id;
没有意义的是,当我删除 AND rowCol = 1
时,查询没有错误。但是有了它,我得到了错误。这是怎么回事?
您的问题是 rowCol
是 window 函数 (ROW_NUMBER()
) 的别名,它们不能出现在 WHERE
子句中。您可以改用 QUALIFY
子句:
SELECT Employee.Salary_Grade_Id,
SUM(Salary_Grades.Grade_Amount) AS total,
ROW_NUMBER() OVER(ORDER BY Employee.Salary_Grade_Id) AS rowCol
FROM Employee, Salary_Grades
WHERE (Employee.Salary_Grade_Id = Salary_Grades.Grade_Id)
GROUP BY Employee.Salary_Grade_Id
QUALIFY rowCol = 1
请注意,您应该使用明确的 JOIN
语法并将查询重写为
SELECT Employee.Salary_Grade_Id,
SUM(Salary_Grades.Grade_Amount) AS total,
ROW_NUMBER() OVER(ORDER BY Employee.Salary_Grade_Id) AS rowCol
FROM Employee
JOIN Salary_Grades ON Employee.Salary_Grade_Id = Salary_Grades.Grade_Id
GROUP BY Employee.Salary_Grade_Id
QUALIFY rowCol = 1
WHERE 子句在窗口之前应用,因此您不能在 WHERE 子句中引用窗口函数。您需要使用子查询:
SELECT
grade_id,
sum(grade_amount) as total
FROM (
SELECT
Employee.Salary_Grade_Id as grade_id,
Salary_Grades.Grade_Amount AS grade_amount,
ROW_NUMBER() OVER(ORDER BY Employee.Salary_Grade_Id) AS rowCol
FROM Employee JOIN Salary_Grades ON Employee.Salary_Grade_Id = Salary_Grades.Grade_Id) x
WHERE rowCol = 1
GROUP BY grade_id;
我还将您的连接谓词移到了 FROM 子句中,作为避免在谓词 Employee.Salary_Grade_Id = Salary_Grades.Grade_Id
被错误删除时意外笛卡尔连接的最佳实践。
我目前正在为工作中的流程编写查询。我试图通过应用 ROW_NUMBER() 函数来获取特定行,然后根据行定位选择行。但是,我得到以下 error:
SQL compilation error: Window function [ROW_NUMBER() OVER (ORDER BY EMPLOYEE.SALARY_GRADE_ID ASC NULLS LAST)] appears outside of SELECT, QUALIFY, and ORDER BY clauses.
查询:
SELECT Employee.Salary_Grade_Id, SUM(Salary_Grades.Grade_Amount) AS total, ROW_NUMBER() OVER(ORDER
BY Employee.Salary_Grade_Id) AS rowCol FROM Employee, Salary_Grades
WHERE (Employee.Salary_Grade_Id = Salary_Grades.Grade_Id AND rowCol = 1) GROUP BY
Employee.Salary_Grade_Id;
没有意义的是,当我删除 AND rowCol = 1
时,查询没有错误。但是有了它,我得到了错误。这是怎么回事?
您的问题是 rowCol
是 window 函数 (ROW_NUMBER()
) 的别名,它们不能出现在 WHERE
子句中。您可以改用 QUALIFY
子句:
SELECT Employee.Salary_Grade_Id,
SUM(Salary_Grades.Grade_Amount) AS total,
ROW_NUMBER() OVER(ORDER BY Employee.Salary_Grade_Id) AS rowCol
FROM Employee, Salary_Grades
WHERE (Employee.Salary_Grade_Id = Salary_Grades.Grade_Id)
GROUP BY Employee.Salary_Grade_Id
QUALIFY rowCol = 1
请注意,您应该使用明确的 JOIN
语法并将查询重写为
SELECT Employee.Salary_Grade_Id,
SUM(Salary_Grades.Grade_Amount) AS total,
ROW_NUMBER() OVER(ORDER BY Employee.Salary_Grade_Id) AS rowCol
FROM Employee
JOIN Salary_Grades ON Employee.Salary_Grade_Id = Salary_Grades.Grade_Id
GROUP BY Employee.Salary_Grade_Id
QUALIFY rowCol = 1
WHERE 子句在窗口之前应用,因此您不能在 WHERE 子句中引用窗口函数。您需要使用子查询:
SELECT
grade_id,
sum(grade_amount) as total
FROM (
SELECT
Employee.Salary_Grade_Id as grade_id,
Salary_Grades.Grade_Amount AS grade_amount,
ROW_NUMBER() OVER(ORDER BY Employee.Salary_Grade_Id) AS rowCol
FROM Employee JOIN Salary_Grades ON Employee.Salary_Grade_Id = Salary_Grades.Grade_Id) x
WHERE rowCol = 1
GROUP BY grade_id;
我还将您的连接谓词移到了 FROM 子句中,作为避免在谓词 Employee.Salary_Grade_Id = Salary_Grades.Grade_Id
被错误删除时意外笛卡尔连接的最佳实践。