2017-05-07 5 views
2

Existe-t-il un moyen d'avoir deux clauses where différentes dans une procédure de sélection dans Interbase firebird?Y at-il un moyen d'avoir deux clause where différente dans une procédure de sélection dans Interbase Firebird?

J'ai créé deux tables qui soutiendront cette question. La sortie désirée est que la procédure de sélection affichera toutes les données de la table SAMPLE_SINGLE même s'il n'y a pas de SINGLE_PK présent dans la table SAMPLE_DOUBLE.

CREATE TABLE SAMPLE_SINGLE ( 
    SINGLE_PK SMALLINT NOT NULL, 
    SINGLE_NAME VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1, 
    SINGLE_AMOUNT SMALLINT, 
    SINGLE_QUANTITY SMALLINT); 

CREATE TABLE SAMPLE_DOUBLE (
    DOUBLE_PK SMALLINT NOT NULL, 
    SINGLE_PK SMALLINT, 
    DOUBLE_QUANTITY SMALLINT); 


CREATE PROCEDURE SELECT_FROM2TABLES 
RETURNS(
    SINGLE_NAME VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ISO8859_1, 
    SINGLE_AMOUNT SMALLINT, 
    SINGLE_QUANTITY SMALLINT, 
    TOTAL_DOUBLE_QUANTITY SMALLINT, 
    REMAINING_QUANTITY SMALLINT) 
AS 
BEGIN 
    FOR 
    SELECT 
     A.SINGLE_NAME, 
     A.SINGLE_AMOUNT, 
     A.SINGLE_QUANTITY, 
     SUM(B.DOUBLE_QUANTITY), 
     A.SINGLE_QUANTITY - SUM(B.DOUBLE_QUANTITY) 

    FROM SAMPLE_SINGLE A, SAMPLE_DOUBLE B 
    WHERE A.SINGLE_PK = B.SINGLE_PK 

    GROUP BY 
    A.SINGLE_NAME, 
     A.SINGLE_AMOUNT, 
     A.SINGLE_QUANTITY 

    INTO 
     :SINGLE_NAME, 
     :SINGLE_AMOUNT, 
     :SINGLE_QUANTITY, 
     :TOTAL_DOUBLE_QUANTITY, 
     :REMAINING_QUANTITY 
    DO 
    BEGIN 
     SUSPEND; 
    END 
END; 

Pour cette procédure de sélection, il affiche uniquement les données de la table SAMPLE_SINGLE qui a une SINGLE_PK présente dans le tableau SAMPLE_DOUBLE en raison de la

FROM SAMPLE_SINGLE A, SAMPLE_DOUBLE B 
     WHERE A.SINGLE_PK = B.SINGLE_PK 

Je veux aussi afficher les données du tableau A ce n'est pas présente dans le tableau B.

Voici les données de l'échantillon,

Table A (SAMPLE_SINGLE) SINGLE_PK SINGLE_NAME SINGLE_AMOUNT SINGLE_QUNATITY 
          1   asdf   100   5 
          2   qwer   50    7 
Table B (SAMPLE_DOUBLE) DOUBLE_PK SINGLE_PK DOUBLE_QUANTITY 
          1   1   3 

Ma sortie désirée dans une procédure de sélection,

SINGLE_NAME SINGLE_AMOUNT SINGLE_QUANTITY TOTAL_DOUBLE_QUANTITY RMAINING_QUANTITY 
    asdf   100   5    3     2 
    qwer   50    7    0     7 

Voici le résultat réel de la procédure ci-dessus, en raison de la clause WHERE A.SINGLE_PK = B.SINGLE_PK, il affichera uniquement la première ligne

SINGLE_NAME SINGLE_AMOUNT SINGLE_QUANTITY TOTAL_DOUBLE_QUANTITY RMAINING_QUANTITY 
    asdf   100   5    3     2 
+0

Interbase et Firebird ne sont pas le même système de base de données. Ils ont beaucoup divergé au cours des 18 dernières années, de sorte que vous ne pouvez pas compter sur une réponse pour s'appliquer à l'autre. Alors choisissez: Firebird ou interbase –

Répondre

2

Le problème est que vous utilisez une jointure implicite (style SQL-89) et l'égalité dans le where exclura automatiquement les lignes où il n'y a aucune ligne dans B. Au lieu de cela, vous devez utiliser l'explicite (style SQL-92) se rejoignent, en particulier un left outer join:

Une jointure externe gauche comprend tous les enregistrements de l'ensemble gauche, mais seulement correspondant à des enregistrements de l'ensemble de droite.

Il faut donc utiliser:

FROM SAMPLE_SINGLE A 
LEFT OUTER JOIN SAMPLE_DOUBLE B ON A.SINGLE_PK = B.SINGLE_PK 

Voir aussi Joins dans le 2.5 Firebird de référence du langage.

+0

merci marque monsieur^_ ^ –