SQL - stronicowanie danych

0

Sytuacja przedstawia sie nastepujaco:
Mam tabele z duza iloscia rekordow (x milionów).

Chce wybierac te dane stronicujac je aby uniknac przetwarzania niepotrzebnych wierszy, a co za tym idzie nie zarzynac serwera.
Dane wyswietlane sa na 'stronach' po 50 rekordow.

Dodatkowo dane sortowane sa po unikalnym identyfikatorze (int) lub nazwie (string) - ale jakby globalnie dla calej tabeli przed wybraniem, a nie tylko juz wybrane rekordy (wiec setna strona bedzie zawierac inne dane przy sortowaniu po identyfikatorze, a inne jesli posortujemy po nazwie rekordu).

O ile z sortowaniem po unikalnym identyfikatorze sie uporalem to z sortowaniem po nazwie, ktora moze sie powtarzac w obrebie wielu identyfikatorow mam juz problem :)

Przyklad uproszczony do samej istoty problemu (dane sortujmy wylacznie rosnaco):

Tabela -

CREATE TABLE [dbo].[TestTbl](
    [ID] [int] NULL,
    [Name] [varchar](10) NULL
) ON [PRIMARY]

Dadane z tabeli wybiera procedura, ktora jako parametry przyjmuje ilosc rekordow na stronie oraz numer strony.
Oto ona:

CREATE PROCEDURE Paging
    @aPageSize int,
    @aPage int,
    @aOrder int
AS
BEGIN
    DECLARE @lFirstRow int
    SET @[email protected]*@aPageSize

    DECLARE @lFirstID int

    SET ROWCOUNT @lFirstRow

    IF @aOrder=0 -- sortowanie po ID
    BEGIN
        SELECT  @lFirstID=[TestTbl].[ID]
        FROM    [TestTbl]
        ORDER BY [TestTbl].[ID] ASC

        SET ROWCOUNT @aPageSize
        SELECT  [ID], [Name]
        FROM    [TestTbl]
        WHERE   [TestTbl].[ID]>[email protected]
        ORDER BY [TestTbl].[ID] ASC
        RETURN 0;
    END

    IF @aOrder=1 -- sortowanie po Nazwie
    BEGIN
-- ???
    END
END

Algorytm stronicowania po ID dziala tak:

  1. licze numer pierwszego rekordu na podstawie rozmiaru oraz numeru strony
    (dla strony 3 bedzie to rekord 150 przy zalozeniu ze strona zawiera 50 pozycji)
  2. wybieram ID pierwszego rekordu na stronie
  3. ustawiam wybranie pierwszych 50 wierszy wyniku zapytania [SET ROWCOUNT @aPageSize]
    (dziala tak jak klauzula TOP)
  4. wybieram rekordy, ktore sa wieksze badz rowne ID wybranemu w kroku 2 (>= bo sortowanie rosnace)
    i wsio.

Jak widac nie ma tutaj specjalnej filozofii, ale problem pojawia się jesli chce posortowac po nazwie gdyz nazwy moga sie powtarzac.
Bedzie to skutkowalo bledna lista wynikow w momencie kiedy na poprzedniej stronie znajda sie te same nazwy co na wybieranej - w skrajnym przypadku wszystkie nazwy identyczne.

Trzeba wiec na pewno posortowac najpierw po nazwie, potem po identyfikatorze (ORDER BY [Name], [ID])...
ale tutaj juz nie mam pomyslow jak to zrealizowac.

Czy przychodzi komus jakis pomysl do glowy?
Z gory dziekuje i pozdrawiam :)

0

Mała poprawka:

  1. licze numer pierwszego rekordu na podstawie rozmiaru oraz numeru strony
    (dla strony 3 bedzie to rekord 150 przy zalozeniu ze strona zawiera 50 pozycji)

Oczywiście miałem na myśli 101 rekord ;) (stronicowanie od 0)

0

Jaki SZBD i technologia dostepu do bazy? Wiele sterownikow pozwala na otwieranie przewijalnych recordsetow, ktore nie pobieraja wszystkiego na raz.

0

MS SQL, ADO.NET

0
SELECT TOP 50 * FROM TestTbl WHERE ID NOT IN (SELECT TOP 100 * ID FROM TestTbl ORDER BY Name) ORDER BY Name

daje Ci od 101 do 150 i tak samo dla id (zmieniasz kolumnę w order by) tylko nie wiem jak to będzie działało dla dalszych stron

0

Super, dziki Misiekd.
Rozwiazanie dziala, sam bym na to nie wpadl, ale zastanawiam sie jak bedzie z wydajnoscia.
Musze to sprawdzic.
Ktos moze juz to przerabial?

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0