Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Comment retourner X enregistrements à partir de la Nième ligne ?

6 réponses
Avatar
Florent CORNEILLE
Bonjour,

Je travaille sur une application Web qui affiche une liste de produits à la
suite d'une recherche. Chaque page contient 10 résultats.

J'aimerais savoir s'il existe un mot clé pour spécifier lors du SELECT que
je ne souhaite récupérrer que 10 lignes à partir de la 31ième par exemple ?

Pour l'instant, j'utilise une requête qui effectue les opérations suivantes :
- Recherche des 40 premiers éléments (avec TOP)
- Recherche des 30 premiers
- Suppression des doublons dans les deux requêtes

Mais je pense qu'au niveau performance, ce n'est pas ce qu'il y a de mieux
car il y a 2 SELECT plus la comparaison.

Ai-je utilisé la meilleure méthode ou bien existe t-il mieux ?

--
L'information n'est rien si elle n'est pas partagée.

6 réponses

Avatar
Philippe T [MS]
Bonjour,

Vous pouvez utiliser la procédure suivante par exemple en lui passant :

Votre requete SELECT sur votre table
Votre clé de tri (unique)
31 (enregistrement de départ)
41 (enregistrement de fin)

<<<
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
<StoredProcedure name="tp_GetSqlRange">

<Object> Allow you to get data from a specific range number to a specific
range number </Object>

<History Author = "Philippe TROTIN - " Date =
"06/02/2004"> </History>

</StoredProcedure>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
CREATE PROCEDURE tp_GetSqlRange
(
@SQL_Table nvarchar(4000), -- Exemple : SELECT * FROM Zip
@TableKey nvarchar(400), -- ZIP_ID
@RangeMin int, -- 5
@RangeMax int, -- 10
@GetTotalCount int = 1
)
AS
BEGIN
SET NOCOUNT ON

DECLARE @SQLString nvarchar(4000)
DECLARE @Count int
DECLARE @ParmDefinition nvarchar(500)
DECLARE @MaxTotalCount int
DECLARE @RangeInversion int
DECLARE @NumberOfRows int

DECLARE @ID_MIN nvarchar(400)

-- Ensure that @RangeMin is fewer than @RangeMax
IF @RangeMin >= @RangeMax
BEGIN
SET @RangeInversion = @RangeMin
SET @RangeMin = @RangeMax
SET @RangeMax = @RangeInversion
END

SET @NumberOfRows = @RangeMax - @RangeMin + 1

-- Get total number of rows (not range dependant)
IF @GetTotalCount = 1
BEGIN
SET @SQLString = 'SELECT @MaxTotalCount = count(*) FROM (' + @SQL_Table +
') req'
SET @ParmDefinition = '@MaxTotalCount int OUTPUT'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @MaxTotalCount OUTPUT
END

-- Get ranges
SET @SQLString = 'SELECT @ID_MIN = ISNULL(z.' + @TableKey + ', '''') FROM
(SELECT TOP ' + CONVERT(nvarchar, @RangeMin) + ' req.' + @TableKey + ' FROM
(' + @SQL_Table + ') req ORDER BY req.' + @TableKey + ') z'
SET @ParmDefinition = '@ID_MIN nvarchar(200) OUTPUT'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @ID_MIN OUTPUT

-- Get data
IF @ID_MIN = ''
BEGIN
SET @SQLString = 'SELECT TOP ' + CONVERT(nvarchar, @NumberOfRows) + ' *
FROM (' + @SQL_Table + ') req ORDER BY req.' + @TableKey
END
ELSE
BEGIN
SET @SQLString = 'SELECT TOP ' + CONVERT(nvarchar, @NumberOfRows) + ' *
FROM (' + @SQL_Table + ') req WHERE req.' + @TableKey + ' >= @ID_MIN ORDER
BY req.' + @TableKey
END

SET @ParmDefinition = '@ID_MIN nvarchar(200)'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @ID_MIN

-- Print the total number of rows
IF @GetTotalCount = 1
BEGIN
SELECT @MaxTotalCount AS TotalNumberOfRows
END
END
GO









----------------------------------------------------------------------
Philippe TROTIN - Microsoft Service France

"Florent CORNEILLE" wrote in
message news:
Bonjour,

Je travaille sur une application Web qui affiche une liste de produits à
la
suite d'une recherche. Chaque page contient 10 résultats.

J'aimerais savoir s'il existe un mot clé pour spécifier lors du SELECT que
je ne souhaite récupérrer que 10 lignes à partir de la 31ième par exemple
?

Pour l'instant, j'utilise une requête qui effectue les opérations
suivantes :
- Recherche des 40 premiers éléments (avec TOP)
- Recherche des 30 premiers
- Suppression des doublons dans les deux requêtes

Mais je pense qu'au niveau performance, ce n'est pas ce qu'il y a de mieux
car il y a 2 SELECT plus la comparaison.

Ai-je utilisé la meilleure méthode ou bien existe t-il mieux ?

--
L'information n'est rien si elle n'est pas partagée.


Avatar
Synopsis
Ca ce gère du côté client, avec ADO.

Voir les propriétés

PageCount, PageSize, AbsolutePage, AbsolutePosition, RecordCount

Un exemple sur :
http://support.microsoft.com/default.aspx?scid=kb;fr;202125

Il faut ouvrir la connection en ClientSide et en KeySet.



"Philippe T [MS]" a écrit dans le message de
news:%
Bonjour,

Vous pouvez utiliser la procédure suivante par exemple en lui passant :

Votre requete SELECT sur votre table
Votre clé de tri (unique)
31 (enregistrement de départ)
41 (enregistrement de fin)

<<<



/*--------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-------------------------------------------------------
<StoredProcedure name="tp_GetSqlRange">

<Object> Allow you to get data from a specific range number to a specific
range number </Object>

<History Author = "Philippe TROTIN - " Date > "06/02/2004"> </History>

</StoredProcedure>
--------------------------------------------------------------------------


----------------------------------------------------------------------------
----------------------------------------------------------------------------
-------------------------------------------------------*/
CREATE PROCEDURE tp_GetSqlRange
(
@SQL_Table nvarchar(4000), -- Exemple : SELECT * FROM Zip
@TableKey nvarchar(400), -- ZIP_ID
@RangeMin int, -- 5
@RangeMax int, -- 10
@GetTotalCount int = 1
)
AS
BEGIN
SET NOCOUNT ON

DECLARE @SQLString nvarchar(4000)
DECLARE @Count int
DECLARE @ParmDefinition nvarchar(500)
DECLARE @MaxTotalCount int
DECLARE @RangeInversion int
DECLARE @NumberOfRows int

DECLARE @ID_MIN nvarchar(400)

-- Ensure that @RangeMin is fewer than @RangeMax
IF @RangeMin >= @RangeMax
BEGIN
SET @RangeInversion = @RangeMin
SET @RangeMin = @RangeMax
SET @RangeMax = @RangeInversion
END

SET @NumberOfRows = @RangeMax - @RangeMin + 1

-- Get total number of rows (not range dependant)
IF @GetTotalCount = 1
BEGIN
SET @SQLString = 'SELECT @MaxTotalCount = count(*) FROM (' + @SQL_Table


+
') req'
SET @ParmDefinition = '@MaxTotalCount int OUTPUT'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @MaxTotalCount OUTPUT
END

-- Get ranges
SET @SQLString = 'SELECT @ID_MIN = ISNULL(z.' + @TableKey + ', '''') FROM
(SELECT TOP ' + CONVERT(nvarchar, @RangeMin) + ' req.' + @TableKey + '


FROM
(' + @SQL_Table + ') req ORDER BY req.' + @TableKey + ') z'
SET @ParmDefinition = '@ID_MIN nvarchar(200) OUTPUT'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @ID_MIN OUTPUT

-- Get data
IF @ID_MIN = ''
BEGIN
SET @SQLString = 'SELECT TOP ' + CONVERT(nvarchar, @NumberOfRows) + ' *
FROM (' + @SQL_Table + ') req ORDER BY req.' + @TableKey
END
ELSE
BEGIN
SET @SQLString = 'SELECT TOP ' + CONVERT(nvarchar, @NumberOfRows) + ' *
FROM (' + @SQL_Table + ') req WHERE req.' + @TableKey + ' >= @ID_MIN ORDER
BY req.' + @TableKey
END

SET @ParmDefinition = '@ID_MIN nvarchar(200)'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @ID_MIN

-- Print the total number of rows
IF @GetTotalCount = 1
BEGIN
SELECT @MaxTotalCount AS TotalNumberOfRows
END
END
GO

>>>

----------------------------------------------------------------------
Philippe TROTIN - Microsoft Service France

"Florent CORNEILLE" wrote in
message news:
> Bonjour,
>
> Je travaille sur une application Web qui affiche une liste de produits à
> la
> suite d'une recherche. Chaque page contient 10 résultats.
>
> J'aimerais savoir s'il existe un mot clé pour spécifier lors du SELECT


que
> je ne souhaite récupérrer que 10 lignes à partir de la 31ième par


exemple
> ?
>
> Pour l'instant, j'utilise une requête qui effectue les opérations
> suivantes :
> - Recherche des 40 premiers éléments (avec TOP)
> - Recherche des 30 premiers
> - Suppression des doublons dans les deux requêtes
>
> Mais je pense qu'au niveau performance, ce n'est pas ce qu'il y a de


mieux
> car il y a 2 SELECT plus la comparaison.
>
> Ai-je utilisé la meilleure méthode ou bien existe t-il mieux ?
>
> --
> L'information n'est rien si elle n'est pas partagée.




Avatar
Florent CORNEILLE
Merci pour votre aide. PageSize et PageCount dans les RecordSet regroupent en
effet les fonctionnalités que je recherche.

Cependant, je suis sous plateforme .Net, je suppose qu'il existe
l'équivalent de ces propriétés dans DataSet, ou une autre classe contenant
des jeux de données. Maintenant que je sais que cela se fait du côté client,
je chercherais ce qui est disponible avec Ado.Net.

Bonne journée,
Avatar
Philippe T [MS]
Bonjour,

Cela dépend car dans ces conditions, vous devez tout de même charger
l'ensemble des enregistrements précédent pour pouvoir faire du paging. La
procédure que je propose ne va que récupérer les enregistrements urtils.

----------------------------------------------------------------------
Philippe TROTIN - Microsoft Service France

"Synopsis" wrote in message
news:4402c2a7$0$20159$
Ca ce gère du côté client, avec ADO.

Voir les propriétés

PageCount, PageSize, AbsolutePage, AbsolutePosition, RecordCount

Un exemple sur :
http://support.microsoft.com/default.aspx?scid=kb;fr;202125

Il faut ouvrir la connection en ClientSide et en KeySet.



"Philippe T [MS]" a écrit dans le message
de
news:%
Bonjour,

Vous pouvez utiliser la procédure suivante par exemple en lui passant :

Votre requete SELECT sur votre table
Votre clé de tri (unique)
31 (enregistrement de départ)
41 (enregistrement de fin)

<<<



/*--------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-------------------------------------------------------
<StoredProcedure name="tp_GetSqlRange">

<Object> Allow you to get data from a specific range number to a
specific
range number </Object>

<History Author = "Philippe TROTIN - " Date >> "06/02/2004"> </History>

</StoredProcedure>
--------------------------------------------------------------------------


----------------------------------------------------------------------------
----------------------------------------------------------------------------
-------------------------------------------------------*/
CREATE PROCEDURE tp_GetSqlRange
(
@SQL_Table nvarchar(4000), -- Exemple : SELECT * FROM Zip
@TableKey nvarchar(400), -- ZIP_ID
@RangeMin int, -- 5
@RangeMax int, -- 10
@GetTotalCount int = 1
)
AS
BEGIN
SET NOCOUNT ON

DECLARE @SQLString nvarchar(4000)
DECLARE @Count int
DECLARE @ParmDefinition nvarchar(500)
DECLARE @MaxTotalCount int
DECLARE @RangeInversion int
DECLARE @NumberOfRows int

DECLARE @ID_MIN nvarchar(400)

-- Ensure that @RangeMin is fewer than @RangeMax
IF @RangeMin >= @RangeMax
BEGIN
SET @RangeInversion = @RangeMin
SET @RangeMin = @RangeMax
SET @RangeMax = @RangeInversion
END

SET @NumberOfRows = @RangeMax - @RangeMin + 1

-- Get total number of rows (not range dependant)
IF @GetTotalCount = 1
BEGIN
SET @SQLString = 'SELECT @MaxTotalCount = count(*) FROM (' + @SQL_Table


+
') req'
SET @ParmDefinition = '@MaxTotalCount int OUTPUT'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @MaxTotalCount
OUTPUT
END

-- Get ranges
SET @SQLString = 'SELECT @ID_MIN = ISNULL(z.' + @TableKey + ', '''')
FROM
(SELECT TOP ' + CONVERT(nvarchar, @RangeMin) + ' req.' + @TableKey + '


FROM
(' + @SQL_Table + ') req ORDER BY req.' + @TableKey + ') z'
SET @ParmDefinition = '@ID_MIN nvarchar(200) OUTPUT'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @ID_MIN OUTPUT

-- Get data
IF @ID_MIN = ''
BEGIN
SET @SQLString = 'SELECT TOP ' + CONVERT(nvarchar, @NumberOfRows) + ' *
FROM (' + @SQL_Table + ') req ORDER BY req.' + @TableKey
END
ELSE
BEGIN
SET @SQLString = 'SELECT TOP ' + CONVERT(nvarchar, @NumberOfRows) + ' *
FROM (' + @SQL_Table + ') req WHERE req.' + @TableKey + ' >= @ID_MIN
ORDER
BY req.' + @TableKey
END

SET @ParmDefinition = '@ID_MIN nvarchar(200)'
EXECUTE sp_executesql @SQLString, @ParmDefinition, @ID_MIN

-- Print the total number of rows
IF @GetTotalCount = 1
BEGIN
SELECT @MaxTotalCount AS TotalNumberOfRows
END
END
GO

>>>

----------------------------------------------------------------------
Philippe TROTIN - Microsoft Service France

"Florent CORNEILLE" wrote in
message news:
> Bonjour,
>
> Je travaille sur une application Web qui affiche une liste de produits
> à
> la
> suite d'une recherche. Chaque page contient 10 résultats.
>
> J'aimerais savoir s'il existe un mot clé pour spécifier lors du SELECT


que
> je ne souhaite récupérrer que 10 lignes à partir de la 31ième par


exemple
> ?
>
> Pour l'instant, j'utilise une requête qui effectue les opérations
> suivantes :
> - Recherche des 40 premiers éléments (avec TOP)
> - Recherche des 30 premiers
> - Suppression des doublons dans les deux requêtes
>
> Mais je pense qu'au niveau performance, ce n'est pas ce qu'il y a de


mieux
> car il y a 2 SELECT plus la comparaison.
>
> Ai-je utilisé la meilleure méthode ou bien existe t-il mieux ?
>
> --
> L'information n'est rien si elle n'est pas partagée.








Avatar
Florent CORNEILLE
Bonnjour,

Merci de cette indication, je pensais que le paging permettait d'indiquer au
serveur les bons enregegistrements à envoyer avant l'envoie. Vu le nombre de
données qu'il y aura à traiter, je me serais vite aperçu des lacunes d'une
telle méthode et testant mon appli.

En effet, je vais opter pour votre méthode. Je trouve étonnant qu'il n'y ai
pas de mot clé pour cette fonctionnalité (avec MySQL, il y a le mot clé LIMIT
qui simplifie grandement les choses)

Merci pour votre aide.

--
L''information n''est rien si elle n''est pas partagée.


"Philippe T [MS]" a écrit :

Bonjour,

Cela dépend car dans ces conditions, vous devez tout de même charger
l'ensemble des enregistrements précédent pour pouvoir faire du paging. La
procédure que je propose ne va que récupérer les enregistrements urtils.



Avatar
Ch.
Si vous utilisez SQL 2005 vous devez pouvoir vous servir de la fonction
row_number()
la requete qui suit ramene les enregistrements de 35 à 40 sur les 40
premiers récupérés
Doit pouvoir etre affinée comme requete !
Mais plutot simple et asser rapide normalement !


select *
from (
select top(40) row_number() over(order by num_mag) as nbr, *
from MATABLE
order by num_mag
) as T
where T.nbr between 35 and 40







"Florent CORNEILLE" a écrit
dans le message de news:

Bonnjour,

Merci de cette indication, je pensais que le paging permettait d'indiquer
au
serveur les bons enregegistrements à envoyer avant l'envoie. Vu le nombre
de
données qu'il y aura à traiter, je me serais vite aperçu des lacunes d'une
telle méthode et testant mon appli.

En effet, je vais opter pour votre méthode. Je trouve étonnant qu'il n'y
ai
pas de mot clé pour cette fonctionnalité (avec MySQL, il y a le mot clé
LIMIT
qui simplifie grandement les choses)

Merci pour votre aide.

--
L''information n''est rien si elle n''est pas partagée.


"Philippe T [MS]" a écrit :

Bonjour,

Cela dépend car dans ces conditions, vous devez tout de même charger
l'ensemble des enregistrements précédent pour pouvoir faire du paging. La
procédure que je propose ne va que récupérer les enregistrements urtils.