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 :

Left outer join en limitant le nombre de ligne retournée à droite, possible ?


Sujet :

MS SQL Server

  1. #1
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Points : 1 628
    Points
    1 628
    Par défaut Left outer join en limitant le nombre de ligne retournée à droite, possible ?
    Bonjour à tous,

    Comme le dit le titre je voudrais faire un left outer join avec une ligne à droite (quelconque).

    Genre shema :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE SITE_VENTE (
    SITE_VENTE _ID INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
    NAME varchar(100)
    );
     
    CREATE TABLE CONTACT (
    CONTACT_ID INTEGER NOT NULL,
    CREATED_DATE DATE NOT NULL,
    FOREIGN KEY (SITE_VENTE _ID) REFERENCES SITE_VENTE (SITE_VENTE _ID),
    URL_CONTACT varchar(400) NOT NULL,
    TYPE_URL varchar(100)
    );
    Requête :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * 
    FROM    SITE_VENTE v
    left outer join CONTACT as c ON c.SITE_VENTE _ID= v.SITE_VENTE _ID AND TYPE_URL = @param
    WHERE v.NAME like '%' +@NAME + '%'

    La requête marche très bien s'il n y a pas de contact ou si y a un seul contact ... Par contre si y en a plusieurs je veux en récupéré qu'un seul n'importe laquel c pour cela que je voudrai limité le nombre de ligne retournée par contact.

    J'ai essayé de bidouiller avec TOP mais en vain ...

    Merci d'avance
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  2. #2
    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 : 42
    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,

    Par contre si y en a plusieurs je veux en récupéré qu'un seul n'importe laquel c pour cela que je voudrai limité le nombre de ligne retournée par contact.
    Cela n'est pas possible, puisqu'on traite des ensembles.
    Je ne comprends pas exactement ce que vous voulez faire.

    Remarque à part : séparez les jointures des filtres, et nommez vos objets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT V.mesColonnesDeV,
    		C.mesColonnesDeC
    FROM dbo.SITE_VENTE v
    LEFT OUTER JOIN dbo.CONTACT AS c ON c.SITE_VENTE _ID = v.SITE_VENTE _ID AND 
    WHERE v.NAME LIKE '%' +@NAME + '%'
    AND V.TYPE_URL = @param
    @++

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Points : 1 628
    Points
    1 628
    Par défaut
    Merci pour votre réponse !

    Je veux simplement récupéré les SITE_VENTE (une seul ligne par site_vente) et un contact et un seul (le premier que je trouve) quand il existe.

    Voici un jeu de données pour teste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    INSERT INTO [dbo].[SITE_VENTE] VALUES (1,Toronto)
    INSERT INTO [dbo].[SITE_VENTE] VALUES (2,Singuapour)
    INSERT INTO [dbo].[SITE_VENTE] VALUES (3,Paris)
     
    INSERT INTO [dbo].[CONTACT] VALUES (1,févr 10 ,1,a@a.com,a)
    INSERT INTO [dbo].[CONTACT] VALUES (2,févr 10 ,1,a@a.com,a)
    INSERT INTO [dbo].[CONTACT] VALUES (3,févr 20 ,2,bariso@a.com,a)
    Je remets le shéma sans erreur cette fois ;-)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE TABLE SITE_VENTE (
    SITE_VENTE_ID INTEGER NOT NULL PRIMARY KEY,
    SITE_NAME varchar(100)
    );
     
    CREATE TABLE CONTACT (
    CONTACT_ID INTEGER NOT NULL,
    CREATED_DATE DATETIME NOT NULL,
    SITE_VENTE_ID INTEGER FOREIGN KEY (SITE_VENTE_ID) REFERENCES SITE_VENTE (SITE_VENTE_ID),
    URL_CONTACT varchar(400) NOT NULL,
    TYPE_URL varchar(100)
    );
    Mon problème donc est que cette requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    DECLARE @NAME varchar(20)
    SET @NAME = 'to'
     
    SELECT * 
    FROM    SITE_VENTE v
    LEFT OUTER JOIN CONTACT AS c ON c.SITE_VENTE_ID= v.SITE_VENTE_ID 
    WHERE v.SITE_NAME LIKE '%' +@NAME + '%'
    AND TYPE_URL = 'a'
    Elle me renvoie deux lignes à cause de la présence de deux ligne dans contact et c'est normal vue la requête mais je n'arrive pas à la modifier de manière à n'avoir qu'un résultat (peu importe le contact ...)

    La seul issue que je vois c'est une requête imbriqué mais je suis persuadé que y a mieux (à tort peut être lol).

    Merci encore
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  4. #4
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Points : 1 628
    Points
    1 628
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Remarque à part : séparez les jointures des filtres, et nommez vos objets :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT V.mesColonnesDeV,
    		C.mesColonnesDeC
    FROM dbo.SITE_VENTE v
    LEFT OUTER JOIN dbo.CONTACT AS c ON c.SITE_VENTE _ID = v.SITE_VENTE _ID AND 
    WHERE v.NAME LIKE '%' +@NAME + '%'
    AND V.TYPE_URL = @param
    @++
    Il n y a pas équivalence entre ma requête et celle-ci, moi je veux avoir les lignes n'ayant pas de contact, c'est pour cette raison que j'utilise l'outer join ... Avec votre requête je n'ai plus le même résultat ... Alors pourquoi me proposez-vous celle-ci ?
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

  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 : 42
    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
    Alors pourquoi me proposez-vous celle-ci ?
    Comme tout le monde, je peux me tromper, désolé ...

    La requête est donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT V.SITE_VENTE_ID,
    		V.SITE_NAME,
    		C.CONTACT_ID,
    		C.CREATED_DATE,
    		C.URL_CONTACT,
    		C.TYPE_URL
    FROM dbo.SITE_VENTE V
    LEFT JOIN dbo.CONTACT AS C ON C.SITE_VENTE_ID = V.SITE_VENTE_ID 
    WHERE V.SITE_NAME LIKE '%' +@NAME + '%'
    AND C.TYPE_URL = 'a'
    Et vous donne ce que vous cherchez, puisque ce sont deux clients différents qui ont effectué un achat sur le site de Toronto.

    Je veux simplement récupéré les SITE_VENTE (une seul ligne par site_vente) et un contact et un seul (le premier que je trouve) quand il existe.
    Vous comprenez bien qu'en faisant une jointure sur la table des contacts, vous n'aurez jamais une ville avec un contact, tout simplement parce que c'est anti-relationnel.

    Vous pouvez é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
    17
    18
    19
    20
    21
    SELECT SITE_VENTE_ID,
    		SITE_NAME,
    		CONTACT_ID,
    		CREATED_DATE,
    		URL_CONTACT,
    		TYPE_URL
    FROM
    (
    	SELECT V.SITE_VENTE_ID,
    			V.SITE_NAME,
    			C.CONTACT_ID,
    			C.CREATED_DATE,
    			C.URL_CONTACT,
    			C.TYPE_URL,
    			ROW_NUMBER() OVER(ORDER BY CONTACT_ID) Indice
    	FROM dbo.SITE_VENTE V
    	LEFT JOIN dbo.CONTACT AS C ON C.SITE_VENTE_ID = V.SITE_VENTE_ID 
    	WHERE V.SITE_NAME LIKE '%' +@NAME + '%'
    	AND C.TYPE_URL = 'a'
    ) TMP
    WHERE Indice = 1
    ou encore :

    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
    WITH
    	CTE AS
    	(
    		SELECT V.SITE_VENTE_ID,
    				V.SITE_NAME,
    				C.CONTACT_ID,
    				C.CREATED_DATE,
    				C.URL_CONTACT,
    				C.TYPE_URL,
    				ROW_NUMBER() OVER(ORDER BY CONTACT_ID) Indice
    		FROM dbo.SITE_VENTE V
    		LEFT JOIN dbo.CONTACT AS C ON C.SITE_VENTE_ID = V.SITE_VENTE_ID 
    		WHERE V.SITE_NAME LIKE '%' +@NAME + '%'
    		AND C.TYPE_URL = 'a'
    	)
    SELECT SITE_VENTE_ID,
    		SITE_NAME,
    		CONTACT_ID,
    		CREATED_DATE,
    		URL_CONTACT,
    		TYPE_URL
    FROM CTE
    WHERE Indice = 1
    @++

  6. #6
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    1 377
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 377
    Points : 1 628
    Points
    1 628
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Comme tout le monde, je peux me tromper, désolé ...
    lol aucun souci, je me demandais juste au cas où j'aurais loupé quelques choses.

    Citation Envoyé par elsuket Voir le message
    Vous comprenez bien qu'en faisant une jointure sur la table des contacts, vous n'aurez jamais une ville avec un contact, tout simplement parce que c'est anti-relationnel.

    Vous pouvez é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
    17
    18
    19
    20
    21
    SELECT SITE_VENTE_ID,
    		SITE_NAME,
    		CONTACT_ID,
    		CREATED_DATE,
    		URL_CONTACT,
    		TYPE_URL
    FROM
    (
    	SELECT V.SITE_VENTE_ID,
    			V.SITE_NAME,
    			C.CONTACT_ID,
    			C.CREATED_DATE,
    			C.URL_CONTACT,
    			C.TYPE_URL,
    			ROW_NUMBER() OVER(ORDER BY CONTACT_ID) Indice
    	FROM dbo.SITE_VENTE V
    	LEFT JOIN dbo.CONTACT AS C ON C.SITE_VENTE_ID = V.SITE_VENTE_ID 
    	WHERE V.SITE_NAME LIKE '%' +@NAME + '%'
    	AND C.TYPE_URL = 'a'
    ) TMP
    WHERE Indice = 1
    ou encore :

    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
    WITH
    	CTE AS
    	(
    		SELECT V.SITE_VENTE_ID,
    				V.SITE_NAME,
    				C.CONTACT_ID,
    				C.CREATED_DATE,
    				C.URL_CONTACT,
    				C.TYPE_URL,
    				ROW_NUMBER() OVER(ORDER BY CONTACT_ID) Indice
    		FROM dbo.SITE_VENTE V
    		LEFT JOIN dbo.CONTACT AS C ON C.SITE_VENTE_ID = V.SITE_VENTE_ID 
    		WHERE V.SITE_NAME LIKE '%' +@NAME + '%'
    		AND C.TYPE_URL = 'a'
    	)
    SELECT SITE_VENTE_ID,
    		SITE_NAME,
    		CONTACT_ID,
    		CREATED_DATE,
    		URL_CONTACT,
    		TYPE_URL
    FROM CTE
    WHERE Indice = 1
    @++
    Ok je vais essayer plutôt comme ça.
    On me l'avait proposé je pensais que je pouvais m'en sortir autrement, mais je m'en contenterai.

    Merci beaucoup pour votre aide
    Échouer, c'est avoir la possibilité de recommencer de manière plus intelligente.

    Twitter Blog Mon site

    Mon article sur l'agilité

Discussions similaires

  1. limiter le nombre de lignes retournées par un select
    Par l.saladdin dans le forum MySQL
    Réponses: 1
    Dernier message: 18/02/2010, 16h56
  2. Réponses: 2
    Dernier message: 17/04/2008, 11h16
  3. LEFT OUTER JOIN et LIMIT
    Par jackfirst72 dans le forum Requêtes
    Réponses: 2
    Dernier message: 13/03/2007, 11h30
  4. Limiter le nombre de lignes retournées
    Par Takusen dans le forum Requêtes
    Réponses: 4
    Dernier message: 05/11/2006, 23h58
  5. concatenation de chaine dans un left outer join
    Par the_edge dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 11/11/2004, 16h08

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