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

MS SQL Server Discussion :

Tri des dates


Sujet :

MS SQL Server

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Février 2011
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2011
    Messages : 176
    Points : 133
    Points
    133
    Par défaut Tri des dates
    Bonjour,

    J'ai une table sous sql server sous cette forme:

    code DEBTF FINTF DEBRD FINRD DEBRP FINRP DEBTX FINTX
    111 2008-04-17 2008-07-01 2008-03-04 2008-06-30 2008-12-07 2009-01-04 2009-01-01 9999-12-31

    Je souhaite avoir chaque fois la date la plus proche à la première colonne (DEBTF ) et qui est inférieure à la 2ème colonne ( FINTF).Si je traiterai cas par cas en comparant chaque fois les dates,je risque de ne pas prendre toutes les possibilités.

    j'ai pensé à faire une procédure de tri sur les dates entre DEBTF et FINTF puisque à chaque fois je l'aurai besoin.

    j'espère que mon problème est clair.
    Merci d'avance pour des suggestions.Si c'est possible avec une tel procédure comment l'a définir.

  2. #2
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Points : 4 792
    Points
    4 792
    Par défaut
    Piste à suivre :

    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
     
    SELECT *,
    DateDiff(day,CONVERT(DateTime,DEBTF,120),CONVERT(DateTime,DateTest ,120)) As NbJours
     FROM
    (
    SELECT code, DEBTF, FINTF, DEBRD As DateTest FROM MaTable
    UNION 
    SELECT code, DEBTF, FINTF, FINRD As DateTest FROM MaTable
    UNION 
    SELECT code, DEBTF, FINTF, DEBRP As DateTest FROM MaTable
    UNION 
    SELECT code, DEBTF, FINTF, FINRP As DateTest FROM MaTable
    UNION 
    SELECT code, DEBTF, FINTF, DEBTX As DateTest FROM MaTable
    UNION 
    SELECT code, DEBTF, FINTF, FINTX As DateTest FROM MaTable
    ) As SousRequete
    WHERE DateTest < FINTF
    Méthode :
    1) on empile ta table en 6 requêtes pour mettre toutes les dates à comparer dans la même colonne
    2) on en profite pour éliminer les dates qui ne seraient pas < FINTF
    3) NbJours est le nombre de jours séparant DateTest de DEBTF ce qui fait qu'il sera facile de trouver le minimum.

  3. #3
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Vous avez d'autres solutions :

    - créer une fonction prenant en paramètre les 6 dates et extrayant la date la qui convient, et l'utiliser pour en faire une colonne calculée, éventuellement indexée

    - Créer une vue indexée remplissant le même besoin

    - Créer un trigger INSTEAD OF INSERT, UPDATE qui value une colonne supplémentaire pour vous. Moins performant ...

    - Changer la conception de votre table en créant à la place une table qui stocke pour chaque code toutes les dates.
    Cette table référencerait les 8 types de dates que vous stockez.
    On aurait donc une table dont les colonnes seraient code, type_date, date.
    La requête s'écrit alors très simplement en utilisant MIN, GROUP BY et HAVING.

    Je pense que la dernière solution est, avec une bonne indexation, la meilleure en terme de conception et de performances

    @++

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Février 2011
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2011
    Messages : 176
    Points : 133
    Points
    133
    Par défaut
    Bonjour à tous,

    Merci pour vos suggestions.
    Je choisis cette solution :
    créer une fonction prenant en paramètre les 6 dates et extrayant la date la qui convient, et l'utiliser pour en faire une colonne calculée, éventuellement indexée
    .

    Mais j'ai pas bien compris comment je ferai l'extraction de la date et la colonne à créer.Pouvez vous m'expliquez de plus.

    Merci.

  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
    Points : 12 371
    Points
    12 371
    Par défaut
    Donc voici 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    CREATE FUNCTION myFunction
    	(
    		@_DEBTF datetime
    		, @_FINTF datetime
    		, @_DEBRD datetime
    		, @_FINRD datetime
    		, @_DEBRP datetime
    		, @_FINRP datetime
    		, @_DEBTX datetime
    		, @_FINTX datetime
    	)
    	RETURNS datetime
    AS
    BEGIN
    	RETURN
    	(
    		SELECT	MIN(min_date)
    		FROM	(
    				SELECT @_DEBRD AS min_date
    				UNION ALL SELECT @_FINRD
    				UNION ALL SELECT @_DEBRP
    				UNION ALL SELECT @_FINRP
    				UNION ALL SELECT @_DEBTX
    				UNION ALL SELECT @_FINTX
    			) AS T
    		WHERE min_date BETWEEN @_DEBTF AND @_FINTF
    	)
    END
    GO
    Que j'ai testé avec plusieurs dates entre @_DEBTF et @_FINTF pour être certain que c'est bien ce que vous voulez.

    Ensuite je me suis créé la table suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE test
    (
    	code int
    	, DEBTF datetime
    	, FINTF datetime
    	, DEBRD datetime
    	, FINRD datetime
    	, DEBRP datetime
    	, FINRP datetime
    	, DEBTX datetime
    	, FINTX datetime
    )
    Et je lui ai ajouté la colonne calculée ZeDate comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE dbo.test
    ADD ZeDate AS(dbo.myFunction(DEBTF, FINTF, DEBRD, FINRD, DEBRP, FINRP, DEBTX, FINTX))
    Un petit test :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT	dbo.test VALUES (111, '2008-04-17', '2008-07-01', '2008-03-04', '2008-06-30', '2008-12-07', '2009-01-04', '2009-01-01', '9999-12-31')
    Puis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT	*
    FROM	dbo.test
    Qui donne :

    code DEBTF FINTF DEBRD FINRD DEBRP FINRP DEBTX FINTX ZeDate
    111 2008-04-17 00:00:00.000 2008-07-01 00:00:00.000 2008-03-04 00:00:00.000 2008-06-30 00:00:00.000 2008-12-07 00:00:00.000 2009-01-04 00:00:00.000 2009-01-01 00:00:00.000 9999-12-31 00:00:00.000 2008-06-30 00:00:00.000
    Notez que vous pouvez indexer la colonne calculée (même si elle n'est pas persistée, ce qui et le cas puisque la fonction n'est pas déterministe) si vous devez à l'avenir écrire des requêtes filtrées sur cette colonne.

    @++

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Février 2011
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2011
    Messages : 176
    Points : 133
    Points
    133
    Par défaut
    Bonjour,

    Merci ça bien marché.

    Comment rendre cette fonction retournant Min et @DEBTF

    Le fait d'ajouter un champ dans le select me pause le problème suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
    Cordialement.

  7. #7
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    C'est normal puisque nous avons écrit :
    La fonction est donc une fonction scalaire, et ne retourne donc qu'une valeur (pas une table !).

    Si vous voulez ajouter une colonne, vous devez modifier la fonction pour qu'elle fasse cela :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    ALTERFUNCTION myFunction
    	(
    		@_DEBTF datetime
    		, @_FINTF datetime
    		, @_DEBRD datetime
    		, @_FINRD datetime
    		, @_DEBRP datetime
    		, @_FINRP datetime
    		, @_DEBTX datetime
    		, @_FINTX datetime
    	)
    	RETURNS TABLE
    AS
    	RETURN
    	(
    		SELECT	MIN(min_date) AS min_date
    			, @_DEBTF AS DEBTF
    		FROM	(
    				SELECT @_DEBRD AS min_date
    				UNION ALL SELECT @_FINRD
    				UNION ALL SELECT @_DEBRP
    				UNION ALL SELECT @_FINRP
    				UNION ALL SELECT @_DEBTX
    				UNION ALL SELECT @_FINTX
    			) AS T
    		WHERE min_date BETWEEN @_DEBTF AND @_FINTF
    	)
    GO
    Dès lors vous ne pourrez pas l'utiliser pour définir une colonne calculée, ni l'appeler dans une requête avant le FROM, ou après le WHERE.

    Vous pourrez en revanche l'utiliser avec l'opérateur APPLY.
    SI vous ne voulez retourner que les lignes pour lesquelles la fonction retourne une valeur, utilisez CROSS APPLY.
    Si en revanche vous voulez les deux colonnes retournées par APPLY, qu'il existe un résultat ou non (les deux colonnes de la fonction sont donc à NULL), utiliser OUTER APPLY.

    Si vous ne voyez pas comment écrire une telle requête, donnez votre requête actuelle (ou son squelette) et ce que vous souhaitez obtenir en sortie.

    @++

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Février 2011
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2011
    Messages : 176
    Points : 133
    Points
    133
    Par défaut
    Bonjour,

    Merci bien,

    j'ai pris info de ces deux lien sur l'intra jointure Apply:

    http://blog.developpez.com/sqlpro/p9...ointure-apply/

    http://technet.microsoft.com/fr-fr/l...6(SQL.90).aspx


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

Discussions similaires

  1. [XL-2007] Tri des dates
    Par Arnaud41 dans le forum Macros et VBA Excel
    Réponses: 23
    Dernier message: 18/04/2013, 15h44
  2. trié des date avec une boucle for each
    Par alex santus dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 03/09/2009, 11h00
  3. tri des dates format jj/MM/année
    Par jacksparo dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 26/01/2009, 17h54
  4. Affichage des dates dans un ListGridView, et tri
    Par mister3957 dans le forum Framework .NET
    Réponses: 4
    Dernier message: 18/03/2007, 11h26
  5. tri des dates par semaine
    Par syldudu dans le forum Access
    Réponses: 17
    Dernier message: 10/10/2006, 11h27

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