IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Choisir le nombre de résultats et commencer lorsque des critères sont remplis


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Par défaut Choisir le nombre de résultats et commencer lorsque des critères sont remplis
    Bonjour,

    J'ai une procédure stockée qui me ramene un tableau avec 4 colonnes et pleins de lignes.

    Mais je voudrais chosir le nombres de lignes retournées et commencer à les prendre en compte lorsqu'il trouve la première ligne dont l'un des champs 2,3 ou 4 est différent de 0. Le premier champs étant toujours différent de 0.

    Exemple :

    Ch1|Ch2|Ch3|Ch4
    *** | 0 | 0 | 0
    *** | 1 | 0 | 3
    *** | 0 | 0 | 0
    *** | 0 | 2 | 2
    *** | 0 | 0 | 0
    *** | 4 | 5 | 0

    Si je choisis 4 lignes, je voudrais :

    *** | 1 | 0 | 3
    *** | 0 | 0 | 0
    *** | 0 | 2 | 2
    *** | 0 | 0 | 0

    Merci d'avance

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 82
    Par défaut
    As-tu un clé primaire dans ta table?
    As-tu moyen d'avoir un ordre dans ta table?

    Si tu n'as pas une de ces 2 conditions c'est plus compliqué.

    Voici un petit lien
    http://www.sqlteam.com/article/retur...ber-in-a-query

  3. #3
    Membre éclairé Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Par défaut
    Et bien ma procédure est peu compliquée avec jointure et compagnie.

    Mais mon champs 1 est unique pour chaque ligne. Il représente la date dans un format bizarre:

    Par exemple aujourd'hui : 27/11/2009 Champs1 = 20091127 (char)

    Si tu parle d'une vraie clé dans la table ça va être plus compliqué car j'ai des sous requetes et des jointures.

    Sinon pour l'ordre et bien mes dates sont rangées dans l'ordre croissant et il n'en manque pas (je veux dire pas de trou)

    20090101 1er septembre
    20090102 2..
    20090103 ...

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2007
    Messages : 82
    Par défaut
    Voilà la solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    Declare @tbl table(_date varchar(20),ch1 int,ch2 int,ch3 int,ch4 int)
    insert into @tbl values('20090101',3, 0 , 0 , 0)
    insert into @tbl values('20090102',9, 0 , 0 , 0)
    insert into @tbl values('20090103',38, 0 , 0 , 0)
    insert into @tbl values('20090104',31, 0 , 2 , 2)
    insert into @tbl values('20090105',13, 0 , 0 , 0)
    insert into @tbl values('20090106',33, 3 , 5 , 2)
    insert into @tbl values('20090107',33, 5 , 3 , 3)
    insert into @tbl values('20090108',33, 7 , 2 , 4)
    insert into @tbl values('20090109',33, 8 , 1 , 0)
     
    Declare @premiereDate  varchar(20)
    select top 1 @premiereDate = _date from @tbl where ch2 <> 0 or ch3 <> 0 or ch4 <> 0 order by _date
     
    declare @nbrligne int
    set @nbrligne = 4
     
    select top(@nbrligne) * from @tbl where _date >= @premiereDate

  5. #5
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour,

    Si vous avez un nombre important de lignes, vous créer une colonne calculée supportée par une fonction, pour pouvoir ensuite l'indexer et gagner en performances.

    Pour cela, reprenons votre table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE maTable
    (
    	ch1 CHAR(8) NOT NULL CONSTRAINT UQ_maTable_ch1 UNIQUE CLUSTERED,
    	ch2 TINYINT NOT NULL,
    	ch3 TINYINT NOT NULL,
    	ch4 TINYINT NOT NULL
    )
    GO
    Créons la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ALTER FUNCTION FnGetSum
    	(
    		@ch2 TINYINT,
    		@ch3 TINYINT,
    		@ch4 TINYINT
    	)
    	RETURNS BIT
    	WITH SCHEMABINDING
    AS
    BEGIN
    	RETURN CASE
    				WHEN @ch2 + @ch3 + @ch4 = 0 THEN NULL
    				WHEN @ch2 = 0 OR @ch3 = 0 OR @ch4 = 0 THEN CAST(0 AS BIT)
    				ELSE CAST(1 AS BIT)
    			END
    END
    GO
    Ajoutons la colonne calculée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ALTER TABLE dbo.MaTable
    ADD flag AS (dbo.FnGetSum(ch2, ch3, ch4)) PERSISTED
    GO
    Peuplons la table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090101', 0 , 0 , 0)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090102', 0 , 0 , 0)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090103', 0 , 0 , 0)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090104', 0 , 2 , 2)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090105', 0 , 0 , 0)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090106', 3 , 5 , 2)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090107', 5 , 3 , 3)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090108', 7 , 2 , 4)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090109', 8 , 1 , 0)
    INSERT INTO dbo.MaTable(ch1, ch2, ch3, ch4) VALUES('20090110', 0 , 0 , 0)
    GO
    Ajoutons un petit index :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CREATE INDEX IX_maTable_ch1_flag
    ON dbo.maTable (ch1, flag)
    GO
    Créons la procédure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE PROCEDURE PsGetData
    	@nbLignes TINYINT
    AS
    BEGIN
    	WITH
    		CTE AS
    		(
    			SELECT TOP 1 ch1
    			FROM dbo.maTable
    			WHERE flag = 0
    		)
    	SELECT TOP (@nbLignes) T.ch1, T.ch2, T.ch3, T.ch4
    	FROM dbo.maTable AS T
    	INNER JOIN CTE AS C
    		ON T.ch1 >= C.ch1
    END
    Il nous suffit maintenant d'exécuter :

    Le format de dates que vous stockez dans ch1 est le format ISO.
    Je ne comprend pas pourquoi on stocke des dates dans des colonnes de type chaîne de caractère.
    Si ces dates étaient stockées sous le type DATETIME ou SMALLDATETIME, on aurait pu écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE PROCEDURE PsGetData
    	@nbLignes TINYINT
    AS
    BEGIN
    	WITH
    		CTE AS
    		(
    			SELECT TOP 1 ch1
    			FROM dbo.maTable
    			WHERE flag = 0
    		)
    	SELECT T.ch1, T.ch2, T.ch3, T.ch4
    	FROM dbo.maTable AS T
    	INNER JOIN CTE AS C
    		ON T.ch1 BETWEEN C.ch1 AND C.ch1 + @nbLignes
    END
    En évitant ainsi l'opérateur TOP qui fait perdre en performances et qui n'est pas ensembliste

    @++

  6. #6
    Membre éclairé Avatar de Chacha35
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2009
    Messages
    264
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2009
    Messages : 264
    Par défaut
    Ok, Merci beaucoup.

    J'ai appris plein de choses.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. appliquer de la couleur lorsque les champs sont remplis
    Par gnimitz dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 14/02/2013, 12h02
  2. [MySQL] Choisir le nombre de résultats à afficher par page
    Par raffa dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 01/01/2009, 12h53
  3. Réponses: 4
    Dernier message: 28/02/2008, 12h26
  4. Réponses: 3
    Dernier message: 04/12/2007, 11h43
  5. [XSL] limiter le nombre de résultat ?
    Par MatMeuh dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 31/10/2004, 19h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo