如何在同一个 select 语句中包含 row_number 的 where 子句?
How to have where clause on row_number within the same select statement?
我无法在同一 select 语句中对行号使用 where 条件。如果我使用不同的 select 语句对行号应用条件,结果将不一致...
SELECT TOP (@lastrow - 1) c.totalRows
,c.ae_effective_enrollment_id
,c.[user_id]
,c.login_name
,c.first_name
,c.last_name
,cm.courseware_title
,cm.courseware_code
,@courseware_id assetId
,c.enrollment_status_id
,CASE
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 0
THEN 'Admin-' + s.description
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 1
THEN 'Self-' + s.description
ELSE s.description
END AS enrollmentStatus
,c.is_group
,CASE
WHEN c.is_self_enrolled = 0
THEN 1
ELSE 0
END is_admin
,CASE
WHEN c.auma_is_assigned = 1
THEN 'Admin-assigned'
WHEN c.auma_is_assigned = 0
THEN 'Self-assigned'
ELSE 'No-My-Plan'
END AS myplanStatus
, master_assignment_id
,ROW_NUMBER() over(partition by cm.courseware_id,c.user_id order by c.is_self_enrolled)as check_row
FROM enrollmentCTE c
INNER JOIN dbo.courseware_master cm ON cm.courseware_id = @courseware_id
LEFT JOIN @statuscodes s ON s.id = c.enrollment_status_id
WHERE check_row=1 and
enrollment_status_id<>4 and
rownumber > @firstrow
AND rownumber < @lastrow
ORDER BY rownumber
check_row
这里不被识别。请帮助
SELECT totalRows, ae_effective_enrollment_id, user_id, login_name, first_name, last_name, check_row FROM
(SELECT TOP (@lastrow - 1) c.totalRows as totalRows
,c.ae_effective_enrollment_id as ae_effective_enrollment_id
,c.[user_id] as user_id
,c.login_name as login_name
,c.first_name as first_name
,c.last_name as last_name
,cm.courseware_title as courseware_title
,cm.courseware_code as courseware_code
,@courseware_id as assetId
,c.enrollment_status_id as enrollment_status_id
,CASE
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 0
THEN 'Admin-' + s.description
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 1
THEN 'Self-' + s.description
ELSE s.description
END AS enrollmentStatus
,c.is_group
,CASE
WHEN c.is_self_enrolled = 0
THEN 1
ELSE 0
END is_admin
,CASE
WHEN c.auma_is_assigned = 1
THEN 'Admin-assigned'
WHEN c.auma_is_assigned = 0
THEN 'Self-assigned'
ELSE 'No-My-Plan'
END AS myplanStatus
, master_assignment_id
,ROW_NUMBER() over(partition by cm.courseware_id,c.user_id order by c.is_self_enrolled)as check_row
FROM enrollmentCTE c
INNER JOIN dbo.courseware_master cm ON cm.courseware_id = @courseware_id
LEFT JOIN @statuscodes s ON s.id = c.enrollment_status_id
WHERE enrollment_status_id<>4 and
rownumber > @firstrow
AND rownumber < @lastrow
ORDER BY rownumber ) t where check_row = 1
注意 - 在第一个 select 语句
中添加所有列名
SQL执行顺序。
FROM
clause
WHERE
clause
GROUP
BY clause
HAVING
clause
SELECT
clause
ORDER BY
clause
check_row 别名是在 select
部分创建的,因此它在上下文中尚不存在
编辑
做了一些测试。似乎无法正确处理。作为临时解决方案,您可以尝试将
ROW_NUMBER() over(...
在 where
子句中还有
编辑:
MSDN website 的另一个选项是
Returning a subset of rows
The following example calculates row numbers for all rows in the SalesOrderHeader table in the order of the OrderDate and returns only rows 50 to 60 inclusive.
USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
使用 CTE
使您的查询基于另一个
;WITH CTE AS(
SELECT c.totalRows
,c.ae_effective_enrollment_id
,c.[user_id]
,c.login_name
,c.first_name
,c.last_name
,cm.courseware_title
,cm.courseware_code
,@courseware_id assetId
,c.enrollment_status_id
,CASE
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 0
THEN 'Admin-' + s.description
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 1
THEN 'Self-' + s.description
ELSE s.description
END AS enrollmentStatus
,c.is_group
,CASE
WHEN c.is_self_enrolled = 0
THEN 1
ELSE 0
END is_admin
,CASE
WHEN c.auma_is_assigned = 1
THEN 'Admin-assigned'
WHEN c.auma_is_assigned = 0
THEN 'Self-assigned'
ELSE 'No-My-Plan'
END AS myplanStatus
, master_assignment_id
,ROW_NUMBER() over(partition by cm.courseware_id,c.user_id order by c.is_self_enrolled) as check_row
FROM enrollmentCTE c
INNER JOIN dbo.courseware_master cm ON cm.courseware_id = @courseware_id
LEFT JOIN @statuscodes s ON s.id = c.enrollment_status_id
WHERE enrollment_status_id<>4
AND rownumber > @firstrow
AND rownumber < @lastrow
)
SELECT TOP (@lastrow - 1) *
FROM CTE
WHERE check_row = 1
ORDER BY rownumber
我无法在同一 select 语句中对行号使用 where 条件。如果我使用不同的 select 语句对行号应用条件,结果将不一致...
SELECT TOP (@lastrow - 1) c.totalRows
,c.ae_effective_enrollment_id
,c.[user_id]
,c.login_name
,c.first_name
,c.last_name
,cm.courseware_title
,cm.courseware_code
,@courseware_id assetId
,c.enrollment_status_id
,CASE
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 0
THEN 'Admin-' + s.description
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 1
THEN 'Self-' + s.description
ELSE s.description
END AS enrollmentStatus
,c.is_group
,CASE
WHEN c.is_self_enrolled = 0
THEN 1
ELSE 0
END is_admin
,CASE
WHEN c.auma_is_assigned = 1
THEN 'Admin-assigned'
WHEN c.auma_is_assigned = 0
THEN 'Self-assigned'
ELSE 'No-My-Plan'
END AS myplanStatus
, master_assignment_id
,ROW_NUMBER() over(partition by cm.courseware_id,c.user_id order by c.is_self_enrolled)as check_row
FROM enrollmentCTE c
INNER JOIN dbo.courseware_master cm ON cm.courseware_id = @courseware_id
LEFT JOIN @statuscodes s ON s.id = c.enrollment_status_id
WHERE check_row=1 and
enrollment_status_id<>4 and
rownumber > @firstrow
AND rownumber < @lastrow
ORDER BY rownumber
check_row
这里不被识别。请帮助
SELECT totalRows, ae_effective_enrollment_id, user_id, login_name, first_name, last_name, check_row FROM
(SELECT TOP (@lastrow - 1) c.totalRows as totalRows
,c.ae_effective_enrollment_id as ae_effective_enrollment_id
,c.[user_id] as user_id
,c.login_name as login_name
,c.first_name as first_name
,c.last_name as last_name
,cm.courseware_title as courseware_title
,cm.courseware_code as courseware_code
,@courseware_id as assetId
,c.enrollment_status_id as enrollment_status_id
,CASE
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 0
THEN 'Admin-' + s.description
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 1
THEN 'Self-' + s.description
ELSE s.description
END AS enrollmentStatus
,c.is_group
,CASE
WHEN c.is_self_enrolled = 0
THEN 1
ELSE 0
END is_admin
,CASE
WHEN c.auma_is_assigned = 1
THEN 'Admin-assigned'
WHEN c.auma_is_assigned = 0
THEN 'Self-assigned'
ELSE 'No-My-Plan'
END AS myplanStatus
, master_assignment_id
,ROW_NUMBER() over(partition by cm.courseware_id,c.user_id order by c.is_self_enrolled)as check_row
FROM enrollmentCTE c
INNER JOIN dbo.courseware_master cm ON cm.courseware_id = @courseware_id
LEFT JOIN @statuscodes s ON s.id = c.enrollment_status_id
WHERE enrollment_status_id<>4 and
rownumber > @firstrow
AND rownumber < @lastrow
ORDER BY rownumber ) t where check_row = 1
注意 - 在第一个 select 语句
中添加所有列名SQL执行顺序。
FROM
clauseWHERE
clauseGROUP
BY clauseHAVING
clauseSELECT
clauseORDER BY
clause
check_row 别名是在 select
部分创建的,因此它在上下文中尚不存在
编辑 做了一些测试。似乎无法正确处理。作为临时解决方案,您可以尝试将
ROW_NUMBER() over(...
在 where
子句中还有
编辑: MSDN website 的另一个选项是
Returning a subset of rows
The following example calculates row numbers for all rows in the SalesOrderHeader table in the order of the OrderDate and returns only rows 50 to 60 inclusive.
USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
使用 CTE
使您的查询基于另一个
;WITH CTE AS(
SELECT c.totalRows
,c.ae_effective_enrollment_id
,c.[user_id]
,c.login_name
,c.first_name
,c.last_name
,cm.courseware_title
,cm.courseware_code
,@courseware_id assetId
,c.enrollment_status_id
,CASE
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 0
THEN 'Admin-' + s.description
WHEN c.enrollment_status_id = 2
AND c.is_self_enrolled = 1
THEN 'Self-' + s.description
ELSE s.description
END AS enrollmentStatus
,c.is_group
,CASE
WHEN c.is_self_enrolled = 0
THEN 1
ELSE 0
END is_admin
,CASE
WHEN c.auma_is_assigned = 1
THEN 'Admin-assigned'
WHEN c.auma_is_assigned = 0
THEN 'Self-assigned'
ELSE 'No-My-Plan'
END AS myplanStatus
, master_assignment_id
,ROW_NUMBER() over(partition by cm.courseware_id,c.user_id order by c.is_self_enrolled) as check_row
FROM enrollmentCTE c
INNER JOIN dbo.courseware_master cm ON cm.courseware_id = @courseware_id
LEFT JOIN @statuscodes s ON s.id = c.enrollment_status_id
WHERE enrollment_status_id<>4
AND rownumber > @firstrow
AND rownumber < @lastrow
)
SELECT TOP (@lastrow - 1) *
FROM CTE
WHERE check_row = 1
ORDER BY rownumber