我正在尝试让UNION ALL使用我正用于分页的CTE。我需要从两个表中获取与一组条件匹配的所有记录,然后分页结果。第一张表格的CTE如下:
;WITH Results_CTE AS (SELECT t1.SomeIntKey1, ROW_NUMBER() OVER (ORDER BY SomeIntKey1) AS RowNum
FROM Table1 t1
LEFT JOIN CalculatedData d ON d.Key = t1.SomeIntKey1
WHERE Postcode LIKE 'CHX 1XX%'
) SELECT * FROM Results_CTE a INNER JOIN CalclatedData d ON a.SomeIntKey1 = d.Key WHERE RowNum >= 0 AND RowNum <= 10 OPTION(RECOMPILE)
第二个表的分页SQL(工作正常)是:
;WITH Results_CTE AS (SELECT t2.SomeIntKey2, ROW_NUMBER() OVER (ORDER BY SomeIntKey2) AS RowNum
FROM Table2 t2
LEFT JOIN CalculatedData d ON d.Key = t1.SomeIntKey2
WHERE Postcode LIKE 'CHX 1XX%'
) SELECT * FROM Results_CTE a INNER JOIN CalclatedData d ON a.SomeIntKey2 = d.Key WHERE RowNum >= 0 AND RowNum <= 10 OPTION(RECOMPILE)
对于组合的分页数据,我尝试过类似的内容:
;WITH Results_CTE AS (SELECT t2.SomeIntKey2, ROW_NUMBER() OVER (ORDER BY SomeIntKey2) AS RowNum
FROM Table2 t2
LEFT JOIN CalculatedData d ON d.Key = t1.SomeIntKey2
WHERE Postcode LIKE 'CHX 1XX%'
UNION ALL
SELECT t1.SomeIntKey1
FROM Table1 t1
LEFT JOIN CalculatedData d ON d.Key = t1.SomeIntKey1
WHERE Postcode LIKE 'CHX 1XX%'
) SELECT * FROM Results_CTE a INNER JOIN CalclatedData d ON a.SomeIntKey2 = d.Key WHERE RowNum >= 0 AND RowNum <= 10 OPTION(RECOMPILE)
但是,这会导致错误:
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
我知道UNION ALLs在最好的时候会让人感到困惑,特别是对于连接,但我基本上从两个表中获取INT键列表,然后将它们连接到包含我需要的数据的第三个(来自这两个表都将出现在Data
表的连接列中。
答案 0 :(得分:5)
您需要确保两个结果集具有相同的列:
WITH Results_CTE AS
(
SELECT
t2.SomeIntKey2 as Key,
ROW_NUMBER() OVER (ORDER BY SomeIntKey2) AS RowNum
FROM
Table2 t2
LEFT JOIN CalculatedData d
ON d.Key = t1.SomeIntKey2
WHERE Postcode LIKE 'CHX 1XX%'
UNION ALL
SELECT
t1.SomeIntKey1 as Key,
0 as RowNum
FROM
Table1 t1
LEFT JOIN CalculatedData d
ON d.Key = t1.SomeIntKey1
WHERE Postcode LIKE 'CHX 1XX%'
)
SELECT * FROM Results_CTE a INNER JOIN CalclatedData d ON a.SomeIntKey2 = d.Key
WHERE RowNum >= 0 AND RowNum <= 10 OPTION(RECOMPILE)
请注意,UNION ALL
的第二部分现在总是为RowNum返回0。如果您想为UNION ALL
的结果提供RowNum列,则需要另一个子查询:
WITH Results_CTE AS
(
SELECT
s.Key,
ROW_NUMBER() OVER (ORDER BY s.Key) AS RowNum
FROM
(
SELECT
t2.SomeIntKey2 as Key,
FROM
Table2 t2
LEFT JOIN CalculatedData d
ON d.Key = t1.SomeIntKey2
WHERE Postcode LIKE 'CHX 1XX%'
UNION ALL
SELECT
t1.SomeIntKey1 as Key
FROM
Table1 t1
LEFT JOIN CalculatedData d
ON d.Key = t1.SomeIntKey1
WHERE Postcode LIKE 'CHX 1XX%'
)
)
SELECT * FROM Results_CTE a INNER JOIN CalclatedData d ON a.SomeIntKey2 = d.Key
WHERE RowNum >= 0 AND RowNum <= 10 OPTION(RECOMPILE)
答案 1 :(得分:1)
你的UNION ALL中的第二个SELECT没有返回相同数量的列,因此问题就出现了。
尝试:
;WITH Results_CTE AS (
SELECT IntKey, ROW_NUMBER() OVER (ORDER BY IntKey) AS RowNum
FROM
(
SELECT t2.SomeIntKey2 AS IntKey
FROM Table2 t2
LEFT JOIN CalculatedData d ON d.Key = t1.SomeIntKey2
WHERE Postcode LIKE 'CHX 1XX%'
UNION ALL
SELECT t1.SomeIntKey1 AS IntKey
FROM Table1 t1
LEFT JOIN CalculatedData d ON d.Key = t1.SomeIntKey1
WHERE Postcode LIKE 'CHX 1XX%'
) t
)
SELECT * FROM Results_CTE a INNER JOIN CalclatedData d ON a.IntKey = d.Key