selection des enregistrements en fonction de sa position dans la t
3 réponses
Eric Maurel
J’ai besoin de découper les donnes d’une table dans 4 autres tables. (Donc
25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25
premières lignes puis je sélectionne les lignes comprises entre l’emplacement
26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d’utiliser la
fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.
Méthode bourine pour exécution en one-shot (attention à la taille du log en fonction du nombre de lignes manipulées) :
/* 1er quart */ SELECT TOP 25 PERCENT ... INTO Table1 + DELETE WHERE ID IN (SELECT TOP 25 PERCENT ID ...)
/* 2ème quart, c'est-à-dire le tiers du reste */ SELECT TOP 33 PERCENT ... INTO Table2 + DELETE WHERE ID IN (SELECT TOP 33 PERCENT ID ...)
/* 3ème quart, c'est-à-dire la moitié du reste */ SELECT TOP 50 PERCENT ... INTO Table3 + DELETE WHERE ID IN (SELECT TOP 50 PERCENT ID ...)
/* 4ème quart : le reste */ SELECT ... INTO Table4 + DELETE
?
Jacques.
"Eric Maurel" a écrit dans le message de news:
J'ai besoin de découper les donnes d'une table dans 4 autres tables. (Donc 25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25 premières lignes puis je sélectionne les lignes comprises entre l'
emplacement
26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d'utiliser la fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.
Merci d'avance.
Eric.
Fred BROUARD
Si vous avez une colonne contenant des nombres entiers dont la dispersion est aléatoire, par exemple auto incrément, alors utilisé la fonction modulo avec 4 pour filtrer le reste sur 0, 1, 2, 3.
Exemple : SELECT * FROM MA_TABLE WHERE MA_COLONNE % 4 = 0
SELECT * FROM MA_TABLE WHERE MA_COLONNE % 4 = 1
...
Sinon, générez cette colonne par un alter table...
A +
Eric Maurel a écrit:
J’ai besoin de découper les donnes d’une table dans 4 autres tables. (Donc 25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25 premières lignes puis je sélectionne les lignes comprises entre l’emplacement 26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d’utiliser la fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.
Merci d’avance.
Eric.
-- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation ********************* http://www.datasapiens.com ***********************
Si vous avez une colonne contenant des nombres entiers dont la dispersion est
aléatoire, par exemple auto incrément, alors utilisé la fonction modulo avec 4
pour filtrer le reste sur 0, 1, 2, 3.
Exemple :
SELECT *
FROM MA_TABLE
WHERE MA_COLONNE % 4 = 0
SELECT *
FROM MA_TABLE
WHERE MA_COLONNE % 4 = 1
...
Sinon, générez cette colonne par un alter table...
A +
Eric Maurel a écrit:
J’ai besoin de découper les donnes d’une table dans 4 autres tables. (Donc
25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25
premières lignes puis je sélectionne les lignes comprises entre l’emplacement
26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d’utiliser la
fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.
Merci d’avance.
Eric.
--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
Si vous avez une colonne contenant des nombres entiers dont la dispersion est aléatoire, par exemple auto incrément, alors utilisé la fonction modulo avec 4 pour filtrer le reste sur 0, 1, 2, 3.
Exemple : SELECT * FROM MA_TABLE WHERE MA_COLONNE % 4 = 0
SELECT * FROM MA_TABLE WHERE MA_COLONNE % 4 = 1
...
Sinon, générez cette colonne par un alter table...
A +
Eric Maurel a écrit:
J’ai besoin de découper les donnes d’une table dans 4 autres tables. (Donc 25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25 premières lignes puis je sélectionne les lignes comprises entre l’emplacement 26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d’utiliser la fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.
Merci d’avance.
Eric.
-- Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com Audit, conseil, expertise, formation, modélisation, tuning, optimisation ********************* http://www.datasapiens.com ***********************
</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
"Eric Maurel" wrote in message news:
J'ai besoin de découper les donnes d'une table dans 4 autres tables. (Donc 25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25 premières lignes puis je sélectionne les lignes comprises entre l'emplacement 26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d'utiliser la fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.
</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
"Eric Maurel" <EricMaurel@discussions.microsoft.com> wrote in message
news:89C8AC70-48D4-43FC-9373-C16B22EE3D09@microsoft.com...
J'ai besoin de découper les donnes d'une table dans 4 autres tables. (Donc
25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25
premières lignes puis je sélectionne les lignes comprises entre l'emplacement
26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d'utiliser la
fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.
</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
"Eric Maurel" wrote in message news:
J'ai besoin de découper les donnes d'une table dans 4 autres tables. (Donc 25% des données dans chaque table.
Par exemple, je dois donc être capable de dire « je sélectionne les 25 premières lignes puis je sélectionne les lignes comprises entre l'emplacement 26 à 50 et ainsi de suite.
Il me semble que sous Oracle nous avions la possibilité d'utiliser la fonction Rowid() qui donnais la position de la ligne dans la table.
Avez-vous une idée pour répondre à ce type de question.