Пейджинговая таблица Еще один вопрос Sql - PullRequest
2 голосов
/ 12 сентября 2011

Sql Server 2005

Структура таблицы

CREATE TABLE [dbo].[Rate](
[RateID] [bigint] IDENTITY(1,1) NOT NULL,
[PairID] [bigint] NOT NULL,
[Open] [decimal](18, 4) NOT NULL,
[Close] [decimal](18, 4) NOT NULL,
[High] [decimal](18, 4) NOT NULL,
[Low] [decimal](18, 4) NOT NULL,
[Difference] [decimal](18, 4) NOT NULL,
[Average] [decimal](18, 4) NOT NULL,
[Percentage] [decimal](18, 4) NOT NULL,
[InfoDate] [datetime] NOT NULL,
[Hourly] [bit] NOT NULL,
[CaptureDateTime] [datetime] NULL,
CONSTRAINT [PK_Rate] PRIMARY KEY CLUSTERED 
(
[RateID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  =   ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Я использую пейджинг для извлечения таблицы как таковой

Select  * from(
SELECT
    (ROW_NUMBER()OVER (ORDER BY InfoDate ASC)) AS RowNo,
    [RateID],
    [PairID],
    [Open],
    [Close],
    [High],
    [Low],
    [InfoDate],
    [CaptureDateTime]
From Rate
) AS T
WHERE t.RowNo 
BETWEEN 200*@PageNumber AND 200 * (@PageNumber+1)-1
ORDER BY RowNo DESC

[Вопрос] Мне нужен запрос, который даст мне эту таблицу

PageNo, StartIndex (первый RateId на этой странице), EndIndex (последний RateId на этой странице), StartDate (первая инфо-дата на этой странице), EndDate (последняя инфо-дата на этой странице).

Ответы [ 2 ]

2 голосов
/ 12 сентября 2011

Вы можете попробовать сделать что-то вроде этого:

DECLARE @PageSize INT = 200

;WITH PagingInfo AS
(
    SELECT
        RateID, InfoDate,
        ROW_NUMBER() OVER (ORDER BY InfoDate) AS RowNo
    FROM 
        dbo.Rate
),
Pages AS
(
    SELECT     
       RateID,
       InfoDate,
       RowNo,
       ((RowNo - 1) / @PageSize) AS PageNo
    FROM PagingInfo
)
SELECT     
    p.PageNo,
    (SELECT RateID FROM Pages p2 WHERE p2.PageNo = p.PageNo AND p2.RowNo % @PageSize = 1) AS 'First RateID',
    (SELECT RateID FROM Pages p2 WHERE p2.PageNo = p.PageNo AND p2.RowNo % @PageSize = 0) AS 'Last RateID',
    (SELECT InfoDate FROM Pages p2 WHERE p2.PageNo = p.PageNo AND p2.RowNo % @PageSize = 1) AS 'First InfoDate',
    (SELECT InfoDate FROM Pages p2 WHERE p2.PageNo = p.PageNo AND p2.RowNo % @PageSize = 0) AS 'Last InfoDate'
FROM Pages p 
WHERE p.RowNo % @PageSize = 0

Два CTE в основном делают то же самое, что и вы - они обеспечивают подкачку данных. Второй CTE Pages дополнительно предоставляет номер страницы для каждой строки.

Из этих CTE я выбираю соответствующий номер страницы (от Pages), а также первый и последний RateID и InfoDate для каждой страницы. Это работает, потому что:

  • первая строка каждой страницы имеет номер строки, который на 1 больше кратного размеру вашей страницы, например 1, 201, 401, 601 и т. Д., Поэтому остаток от целочисленного деления на размер вашей страницы всегда будет 1

  • последняя строка каждой страницы имеет номер строки, который делится на размер вашей страницы (например, 200, 400, 600 и т. Д.), И, таким образом, остаток от целочисленного деления составляет 0

На основании этой информации я могу выбрать первые и последние RateID и InfoDate из Pages CTE для каждой страницы.

2 голосов
/ 12 сентября 2011

Примерно так (не проверено).

SELECT @PageNumber as PageNo,
       min(RateID) as StartIndex,
       max(RateID) as EndIndex,
       min(infoDate) as StartDate,
       max(infoDate) as EndDate 
FROM (
      SELECT
          (ROW_NUMBER()OVER (ORDER BY InfoDate ASC)) AS RowNo,
          [RateID],
          [InfoDate]
      FROM Rate
     ) AS T
WHERE t.RowNo BETWEEN 200*@PageNumber AND 200 * (@PageNumber+1)-1

Если вы хотите, чтобы все страницы были выполнены в одном запросе, вы можете использовать это вместо этого.

SELECT PageNo + 1 as PageNo,
       MIN(RateID) as StartIndex,
       MAX(RateID) as EndIndex,
       MIN(infoDate) as StartDate,
       MAX(infoDate) as EndDate 
FROM (
      SELECT
          (ROW_NUMBER() OVER(ORDER BY InfoDate ASC) - 1) / @PageSize AS PageNo,
          [RateID],
          [InfoDate]
      FROM Rate
     ) AS T
GROUP BY PageNo
ORDER BY PageNo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...