これがあり、設定された合計でエラーが発生します。 cteに何度もアクセスできないのはなぜですか?
ALTER PROCEDURE [dbo].[GetLeaguePlayers]
(
@idleague int,
@pageNumber int,
@pageSize int,
@total int OUTPUT
)
AS
WITH CTEPlayers AS
(
SELECT ROW_NUMBER() OVER (ORDER BY p.Name) AS RowNumber, p.Id, p.Name, t.Name AS Team
FROM Players p INNER JOIN Teams t ON p.IdTeam=t.Id INNER JOIN Leagues l ON l.Id=t.IdLeague
WHERE l.Id=@idleague
)
SELECT Id, Name
FROM CTEPlayers c
WHERE RowNumber>@pageSize*(@pageNumber-1) AND RowNumber<@pageSize*@pageNumber;
SET @total = ( SELECT COUNT(*) FROM CTEPlayers )
CTE
は基本的に使い捨てのビューです。単一のステートメントに対してのみ持続し、その後自動的に消えます。
次のオプションがあります。
CTE
を再定義します。これは、WITH...
から定義の最後までSET
の前にコピーアンドペーストするだけの簡単なものです。
結果を#temp
テーブルまたは@table
変数に入れます
結果を実際の表に具体化し、それを参照する
CTEからSELECT COUNT
にわずかに変更します。
。
SELECT @total = COUNT(*)
FROM Players p
INNER JOIN Teams t
ON p.IdTeam=t.Id
INNER JOIN Leagues l
ON l.Id=t.IdLeague
WHERE l.Id=@idleague
上記の答えはどれも正しくありません... CTEを1回実行して、目的の結果を達成できます。
ALTER PROCEDURE [dbo].[GetLeaguePlayers]
(
@idleague int,
@pageNumber int,
@pageSize int,
@total int OUTPUT
)
AS
WITH CTEPlayers AS
(
SELECT p.Id, p.Name, t.Name AS Team
FROM Players p INNER JOIN Teams t ON p.IdTeam=t.Id INNER JOIN Leagues l ON l.Id=t.IdLeague
WHERE l.Id=@idleague
),
TotalCount AS
(
SELECT COUNT(*) AS Total FROM CTEPlayers
),
Final_Result AS
(
SELECT ROW_NUMBER() OVER (ORDER BY p.Name) AS RowNumber, p.Id, p.Name, t.Name AS Team,
(SELECT Total FROM TotalCount) AS Total
FROM CTEPlayers
)
SELECT Id, Name, @total = Total
FROM Final_Results c
WHERE RowNumber>@pageSize*(@pageNumber-1) AND RowNumber<@pageSize*@pageNumber;
CTEは、定義により、1つのステートメントに対してのみ有効です。
インラインテーブル値関数 を作成し、これを好きなだけ使用できます。インライン関数は、名前が示唆することを行います。そのクエリは、それを使用するクエリの一部になります(個別に実行され、行セットとして使用される非インライン関数とは対照的です)。
この場合、私はこれを使用します:
ALTER PROCEDURE [dbo].[GetLeaguePlayers]
(
@idleague int,
@pageNumber int,
@pageSize int,
@total int OUTPUT
)
AS
WITH CTEPlayers AS
(
SELECT ROW_NUMBER() OVER (ORDER BY p.Name) AS RowNumber,
COUNT(1) OVER () AS RecordCount,
p.Id, p.Name,
t.Name AS Team
FROM Players p
INNER JOIN Teams t ON p.IdTeam=t.Id
INNER JOIN Leagues l ON l.Id=t.IdLeague
WHERE l.Id=@idleague
)
SELECT RowNumber,
CAST(CEILING(CAST(RecordCount AS FLOAT) / CAST(@pageSize AS FLOAT)) AS INT) PageCount,
RecordCount,
Id,
Name
FROM CTEPlayers c
WHERE RowNumber > @pageSize*(@pageNumber-1) AND RowNumber < @pageSize*@pageNumber;