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 :

Problème interprétation SELECT FROM (SELECT . . .)


Sujet :

Développement SQL Server

  1. #1
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2009
    Messages
    1 030
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2009
    Messages : 1 030
    Points : 4 203
    Points
    4 203
    Par défaut Problème interprétation SELECT FROM (SELECT . . .)
    Bonjour,

    J'ai un soucis avec une requête imbriquée dans un FROM. Ca me bloque depuis plusieurs jours donc j'en viens à l'extrémité de vous demander de l'aide. Je préviens je suis débutant en SQL Server et .NET (je suis stagiaire depuis 4 mois et demi).

    J'ai 4 tables dont 3 liées par héritage à l'une d'entre elles. Les tables Regle_Produit , Regle_Produit_Hasard , Achat_Groupe qui dérivent de la table Regle .

    Les sous-tables possèdent en clé étrangère l'identifiant de la sur-table Regle : id_regle.

    Alors j'ai réussi à concevoir une requète, qui me récupère, par rapport à un id_regle spécifié et inscrit dans la table Regle, le nom de la sous-table qui contient cette règle (en détails).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    select COALESCE(CASE WHEN RP.id_regle_produit is not null then 'ECommerce_CrossV2_Regle_Produit' end, CASE WHEN PH.id_regle_produit_hasard is not null then 'ECommerce_CrossV2_Produit_Hasard' end, case when AG.id_regle_achat_groupe is not null then 'ECommerce_CrossV2_Achat_Groupe' end) 
    from ECommerce_CrossV2_Regle as R1 
    LEFT JOIN ECommerce_CrossV2_Regle_Produit as RP ON R1.id_regle = RP.id_regle_produit
    LEFT JOIN ECommerce_CrossV2_Regle as R2 ON R1.id_regle = R2.id_regle
    LEFT JOIN  ECommerce_CrossV2_Produit_Hasard as PH ON R2.id_regle = PH.id_regle_produit_hasard
    LEFT JOIN ECommerce_CrossV2_Regle as R3 ON R1.id_regle = R3.id_regle
    LEFT JOIN  ECommerce_CrossV2_Achat_Groupe as AG ON R3.id_regle = AG.id_regle_achat_groupe
    WHERE R1.id_regle = 2;
    Lorsque que je met ce paramètre à 2, cela me retourne bien comme résultat ECommerce_CrossV2_Produit_Hasard

    Voila ce que j'aimerais faire et que je n'arrive pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from (ma grosse requete);
    Le résultat de la grosse requête est considéré comme une table et non une chaîne de caractère. Aussi je me retrouve avec comme résultat : ECommerce_CrossV2_Produit_Hasard

    alors que je voudrais le contenu de la table ECommerce_CrossV2_Produit_Hasard. Il faudrait donc que je puisse, en SQL, récupérer un contenu de table et l'insérer dans la requête. J'aimerais éviter les procédures stockées ou devoir jongler entre du code CLR et SQL Server, ce qui diminuerait les performances.

    J'ai essayé de mettre ma première requête en tant que fonction scalaire retournant un nvarchar(50). Cette fonction fonctionne mais je n'arrive pas à l'invoquer dans le FROM.

    Si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from dbo.recherche_table_regle(2);
    le compilateur considère que dbo.recherche_table_regle(2) devrait être une table et me renvoit une erreur.

    Selon vous, comment faire en sorte de faire une sorte d'évaluation de la fonction avant l'exécution de la requête pour qu'il fasse bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from ECommerce_CrossV2_Produit_Hasard;
    Merci d'avance pour votre aide.

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 758
    Points : 52 535
    Points
    52 535
    Billets dans le blog
    5
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT *
    FROM
    (
    SELECT COALESCE(CASE WHEN RP.id_regle_produit IS NOT NULL then 'ECommerce_CrossV2_Regle_Produit' end, CASE WHEN PH.id_regle_produit_hasard IS NOT NULL then 'ECommerce_CrossV2_Produit_Hasard' end, case when AG.id_regle_achat_groupe IS NOT NULL then 'ECommerce_CrossV2_Achat_Groupe' end) 
    FROM ECommerce_CrossV2_Regle AS R1 
    LEFT JOIN ECommerce_CrossV2_Regle_Produit AS RP ON R1.id_regle = RP.id_regle_produit
    LEFT JOIN ECommerce_CrossV2_Regle AS R2 ON R1.id_regle = R2.id_regle
    LEFT JOIN  ECommerce_CrossV2_Produit_Hasard AS PH ON R2.id_regle = PH.id_regle_produit_hasard
    LEFT JOIN ECommerce_CrossV2_Regle AS R3 ON R1.id_regle = R3.id_regle
    LEFT JOIN  ECommerce_CrossV2_Achat_Groupe AS AG ON R3.id_regle = AG.id_regle_achat_groupe
    WHERE R1.id_regle = 2;
    ) AS T
    Il est important de nommer la table dérivée (ici en T).

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2009
    Messages
    1 030
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2009
    Messages : 1 030
    Points : 4 203
    Points
    4 203
    Par défaut
    Désolé, j'avais déja corrigé cette erreur. J'ai oublié de mettre cette correction dans le post.

    Voici la VRAIE requète :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT *
    FROM
    (
    SELECT COALESCE(CASE WHEN RP.id_regle_produit IS NOT NULL then 'ECommerce_CrossV2_Regle_Produit' end, CASE WHEN PH.id_regle_produit_hasard IS NOT NULL then 'ECommerce_CrossV2_Produit_Hasard' end, case when AG.id_regle_achat_groupe IS NOT NULL then 'ECommerce_CrossV2_Achat_Groupe' end) as C
    FROM ECommerce_CrossV2_Regle AS R1 
    LEFT JOIN ECommerce_CrossV2_Regle_Produit AS RP ON R1.id_regle = RP.id_regle_produit
    LEFT JOIN ECommerce_CrossV2_Regle AS R2 ON R1.id_regle = R2.id_regle
    LEFT JOIN  ECommerce_CrossV2_Produit_Hasard AS PH ON R2.id_regle = PH.id_regle_produit_hasard
    LEFT JOIN ECommerce_CrossV2_Regle AS R3 ON R1.id_regle = R3.id_regle
    LEFT JOIN  ECommerce_CrossV2_Achat_Groupe AS AG ON R3.id_regle = AG.id_regle_achat_groupe
    WHERE R1.id_regle = 2
    ) AS T
    qui donne bien comme résultat ECommerce_CrossV2_Produit_Hasard au lieu du contenu de cette table.

  4. #4
    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,

    Si vous êtes sous SQL Server 2005 ou 2008, vous pouvez aussi utiliser une expression de table commune :

    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
    30
    WITH
    	CTE (C) AS
    	(
    		SELECT COALESCE
    				(
    					CASE
    						WHEN RP.id_regle_produit IS NOT NULL THEN 'ECommerce_CrossV2_Regle_Produit'
    					END,
    					CASE
    						WHEN PH.id_regle_produit_hasard IS NOT NULL THEN 'ECommerce_CrossV2_Produit_Hasard'
    					END,
    					CASE
    						WHEN AG.id_regle_achat_groupe IS NOT NULL THEN 'ECommerce_CrossV2_Achat_Groupe'
    					END
    				) AS C
    		FROM dbo.ECommerce_CrossV2_Regle AS R1 
    		LEFT JOIN dbo.ECommerce_CrossV2_Regle_Produit AS RP
    			ON R1.id_regle = RP.id_regle_produit
    		LEFT JOIN dbo.ECommerce_CrossV2_Regle AS R2
    			ON R1.id_regle = R2.id_regle
    		LEFT JOIN dbo.ECommerce_CrossV2_Produit_Hasard AS PH
    			ON R2.id_regle = PH.id_regle_produit_hasard
    		LEFT JOIN dbo.ECommerce_CrossV2_Regle AS R3
    			ON R1.id_regle = R3.id_regle
    		LEFT JOIN dbo.ECommerce_CrossV2_Achat_Groupe AS AG
    			ON R3.id_regle = AG.id_regle_achat_groupe
    		WHERE R1.id_regle = 2
    	)
    SELECT C
    FROM CTE
    Les plans de requêtes sont identiques d'une écriture à l'autre

    @++

  5. #5
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2009
    Messages
    1 030
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2009
    Messages : 1 030
    Points : 4 203
    Points
    4 203
    Par défaut
    Merci beaucoup. J'ai au moins une solution "propre" à proposer, là où mes collègues n'avaient rien trouvé.

    Dommage que certaines bases tournent encore sous SQL Server 2000, mais je conserve cette solution pour quand les migrations seront totales. En attendant j'imagine que je vais devoir segmenter en plusieurs requêtes, sauf si vous avez une solution compatible SQL Server 2000.

    @++

Discussions similaires

  1. Problème interprétation navigateur sur SELECT
    Par qwertz1 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 04/02/2013, 19h08
  2. Select * from (select * from T)
    Par hadi2007 dans le forum Informix
    Réponses: 3
    Dernier message: 09/08/2009, 11h36
  3. select * from (select * from mabase) Impossible ?
    Par maniolo dans le forum Sybase
    Réponses: 9
    Dernier message: 04/03/2009, 13h33
  4. Problème lors d'un select * from table
    Par smaildba dans le forum SQL
    Réponses: 1
    Dernier message: 12/11/2008, 12h36
  5. Réponses: 6
    Dernier message: 20/11/2007, 11h14

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