Sql server Union All使用不同的排序和分页组合2个表
我使用的是MS-SQL 2012,有两个表包含类似的数据字段类型 我正在编写一个存储过程,需要使用特定的排序顺序从表1中获取10条记录,并使用不同的排序顺序从表2中获取10条记录 我还需要使用分页 差不多Sql server Union All使用不同的排序和分页组合2个表,sql-server,Sql Server,我使用的是MS-SQL 2012,有两个表包含类似的数据字段类型 我正在编写一个存储过程,需要使用特定的排序顺序从表1中获取10条记录,并使用不同的排序顺序从表2中获取10条记录 我还需要使用分页 差不多 SELECT Field1, Field2, Field3 FROM TableAAAA ORDER BY FieldSort1 DESC --> DateTime OFFSET (@PageIndex-1) * 10 ROWS FETCH NEXT @Pa
SELECT Field1, Field2, Field3
FROM TableAAAA
ORDER BY FieldSort1 DESC --> DateTime
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
UNION ALL
SELECT Field1, Field2, Field3
FROM TableBBBB
ORDER BY FieldSort2 --> INT
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
如果我使用UNION ALL,我只能在其末尾进行排序,因此无法使用上述代码。您可以使用派生表或CTE:
WITH cteA AS (
SELECT Field1, Field2, Field3
FROM TableAAAA
ORDER BY FieldSort1
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
),
cteB AS (
SELECT Field1, Field2, Field3
FROM TableBBBB
ORDER BY FieldSort2
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
)
SELECT * FROM cteA
UNION ALL
SELECT * FROM cteB
您可以使用派生表或CTE:
WITH cteA AS (
SELECT Field1, Field2, Field3
FROM TableAAAA
ORDER BY FieldSort1
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
),
cteB AS (
SELECT Field1, Field2, Field3
FROM TableBBBB
ORDER BY FieldSort2
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
)
SELECT * FROM cteA
UNION ALL
SELECT * FROM cteB
这里有一个方法(因为你知道第一个方法只会是页面大小
WITH t1 AS
(
SELECT Field1, Field2, Field3, ROW_NUMBER() OVER (ORDER BY FieldSort1) AS outerSort1, 0 as outerSort2
FROM TableAAAA
ORDER BY FieldSort1
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
), t2 AS
(
SELECT Field1, Field2, Field3, 0 as outerSort1, ROW_NUMBER() OVER (ORDER BY FieldSort2) AS outerSort2
FROM TableBBBB
ORDER BY FieldSort2
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
)
SELECT Field1, Field2, Field3 FROM T1
UNION ALL
SELECT Field1, Field2, Field3 FROM T2
ORDER BY outerSort1, outerSort2
这里有一个方法(因为你知道第一个方法只会是页面大小
WITH t1 AS
(
SELECT Field1, Field2, Field3, ROW_NUMBER() OVER (ORDER BY FieldSort1) AS outerSort1, 0 as outerSort2
FROM TableAAAA
ORDER BY FieldSort1
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
), t2 AS
(
SELECT Field1, Field2, Field3, 0 as outerSort1, ROW_NUMBER() OVER (ORDER BY FieldSort2) AS outerSort2
FROM TableBBBB
ORDER BY FieldSort2
OFFSET (@PageIndex-1) * 10 ROWS
FETCH NEXT @PageSize ROWS ONLY
)
SELECT Field1, Field2, Field3 FROM T1
UNION ALL
SELECT Field1, Field2, Field3 FROM T2
ORDER BY outerSort1, outerSort2
如果在每个SELECT中使用TOP,则可以对UNION ALL的两侧单独排序。或者,您可以人工构造某种“排序方式”列,该列将包含一个值,您可以根据该值对整个结果集进行逻辑排序。Top X不允许我使偏移量正常工作…我相信即使您使用Top 100%?如果您使用CTE会怎么样?表1 SortBy是一个日期,表2是一个整数…如果您在每个SELECT中使用Top,则可以对联合的两侧单独排序。可选首先,你可以人工构造某种“SortBy”列,其中包含一个值,你可以按照该值对整个结果集进行逻辑排序。Top X不允许我使偏移量正常工作…我相信即使使用Top 100%?如果使用CTE呢?表1 SortBy是日期,表2是Int…问题是每个表都有一个“不同”排序我知道。我以前从未使用过偏移量,所以可能我不知道与ORDER BY的交互作用。但是FieldSort1可能不同于FieldSort2。问题是每个表都有一个“不同”的"SortBy知道。我以前从未使用过偏移量,因此可能我不知道与ORDER BY的交互。但是FieldSort1可能不同于FieldSort2。为什么在联合结束时需要ORDER BY ALL.。如果结果已经由CTE排序???@SDDeveloper-它们可能是,也可能不是,规范不要求它们对于UNION,所有结果都是有序的,只是它们是一个UNION。您可以只使用排序列本身,而不是行号:
,t1为(选择…Sort1=FieldSort1,Sort2=NULL FROM…),t2为(选择…Sort1=NULL,Sort2=FieldSort2 FROM…)选择…ORDER BY Sort2 ASC,Sort1 DESC;
@AndriyM-非常正确。在我的原始设计中,我没有两个排序列,但尝试将它们合并。因为我没有执行该行编号()技术上不需要。但是,在某些平台上,ORDER BY和nulls可能会出现一些问题,所以请注意。@SDDeveloper-是的。使用CTE,优化器将选择如何存储临时数据,并且它通常比您更擅长做出这些选择。此外,CTE上的语法更简单,因此我几乎在所有情况下都更喜欢它。如果需要针对多个查询运行临时表,则只需要临时表。为什么需要UNION ALL末尾的ORDER BY..如果结果已经由CTE排序???@SDDeveloper-它们可能是,也可能不是,UNION ALL规范不要求结果是有序的,只是它们是一个UNION。而不是行号rs您可以只使用排序列本身:将t1作为(选择…Sort1=FieldSort1,Sort2=NULL FROM…),t2作为(选择…Sort1=NULL,Sort2=FieldSort2 FROM…)选择…ORDER BY Sort2 ASC,Sort1 DESC;
@AndriyM-非常正确。在我的原始设计中,我没有两个排序列,但尝试将它们合并。因为我没有执行该行编号()技术上不需要。但是,在某些平台上,ORDER BY和nulls可能会出现一些问题,所以请注意。@SDDeveloper-是的。使用CTE,优化器将选择如何存储临时数据,并且它通常比您更擅长做出这些选择。此外,CTE上的语法更简单,因此我几乎在所有情况下都更喜欢它。只有在需要针对多个查询运行临时表时才需要临时表。