1
votes

Pourquoi UNION ne fonctionne-t-il pas dans CTE ou sous-requête?

J'essaye d'exécuter une requête via System i Navigator qui sélectionne le résultat combiné d'une union.

Cela fonctionne bien:

SELECT *
FROM
    (SELECT AF15VC FROM DB.AF
     UNION
     SELECT AF15VC FROM BATCH.AFM
    ) AS AF

Alors pourquoi ne ça marche pas?

WITH CTE AS (
    SELECT AF15VC FROM DB.AF
    UNION
    SELECT AF15VC FROM BATCH.AFM
)
SELECT *
FROM CTE

Et pourquoi ça ne marche pas?

SELECT AF15VC FROM DB.AF
UNION
SELECT AF15VC FROM BATCH.AFM

Dans les deux cas, j'obtiens ceci erreur:

État SQL: 42601

Code du fournisseur: -199

Message: [SQL0199]

Mot clé UNION pas attendu. Jetons valides:). Cause . . . . . : Le mot-clé UNION n'était pas prévu ici. Une erreur de syntaxe a été détectée au niveau du mot clé UNION. La liste partielle des jetons valides est). Cette liste suppose que le l'instruction est correcte jusqu'au mot-clé inattendu. L'erreur peut être plus tôt dans l'instruction, mais la syntaxe de l'instruction semble être valable jusqu'à présent. Récupération . . . : Examinez l'instruction SQL dans la zone du mot-clé spécifié. Un délimiteur deux-points ou SQL peut être disparu. SQL exige que les mots réservés soient délimités lorsqu'ils sont utilisé comme nom. Corrigez l'instruction SQL et réessayez la requête.

J'ai également essayé UNION ALL sans changement dans le résultat.

Mise à jour:

Puisque les gens continuent de penser que je ne montre pas les requêtes réelles, j'ai ajouté des captures d'écran. Voici la première requête qui fonctionne correctement et les deux autres échouent:

query 1 requête 2 query 3


12 commentaires

Avez-vous essayé d'ajouter ; ?


@LukaszSzozda oui. J'ai également essayé de supprimer AS et AS AF .


Ok, mais cette instruction unique ou fait-elle partie d'un script / procédure stockée?


Déclaration unique @LukaszSzozda


Intéressant, ces deux syntaxes fonctionnent pour moi. Je suis à la version 7.2, dans quelle version êtes-vous?


@jmarkmurphy 7.1


Montrez-vous l'intégralité de la requête ou une version simplifiée que vous n'avez pas réellement exécutée? Les deux requêtes que vous avez affichées devraient fonctionner. Une chose que vous voudrez peut-être considérer (pour les performances uniquement) est UNION ALL . Mais, voir mes commentaires à Charles ci-dessous.


@jmarkmurphy La requête prévue est plus complexe, mais je ne peux pas non plus exécuter l'une des requêtes triviales présentées dans mon article. Je suis stupéfait.


Veuillez nous montrer la requête exacte qui échoue (vous pouvez renommer les tables et les colonnes si vous n'êtes pas autorisé à publier l'original mais montrez-nous l'intégralité de la requête, pas une version supprimée)


@ yper-crazyhat-cubeᵀᴹ Les requêtes de ma question sont les requêtes exactes qui échouent. J'ai ajouté des captures d'écran pour dissiper la confusion.


@jmarkmurphy Les requêtes de ma question sont les requêtes exactes qui échouent. J'ai ajouté des captures d'écran pour dissiper la confusion.


Les trois formulaires fonctionnent sur mon AS400 exécuté localement et à distance.


3 Réponses :


1
votes

Fonctionne très bien pour moi sur la version 7.2

with cte as (
select pmco#, pmmanf
from dtdata.pdpmast
union 
select pmco#, pmmanf
from devqdata.pdpmast
)
select * from cte;

Remarque: utilisez UNION ALL si vous ne l'avez pas ou ne l'avez pas se soucier des doublons. UNION élimine les doublons et s'il n'y en a pas, cela signifie beaucoup de traitement gaspillé.


4 commentaires

La vraie requête est plus complexe. J'essaye de faire une requête où la source est 4 tables qui sont identiques dans la structure mais contiennent des données de périodes différentes. Quelqu'un avant moi y est parvenu en faisant ceci: {requête sur la table 1} union {requête identique sur la table 2} etc ... Pour éliminer les 3 requêtes copiées-collées, je préfère faire ceci à la place si possible: requête sur {table 1 union table2 etc ...}.


S'il est vrai qu'un fullselect est une combinaison de sous-sélections , de la table-clause (au moins à v7.1 et versions ultérieures, et je croyez beaucoup plus tôt). peut contenir une expression de table imbriquée qui ressemble à [LATERAL] (fullsellect) [correlation-clause] .


J'ai pu consulter un manuel v5r3, et même là, la syntaxe CTE est table-identifier [(column-name, ...)] AS (fullselect [order-by-clause] [fetch-clause]) . L'expression de table imbriquée est similaire, sauf dans la documentation de la version 7.1 et antérieure, la clause de corrélation est un composant obligatoire. Et par test, en v7.2, la clause de corrélation est toujours requise. Il aurait pu être rendu facultatif à un TR plus tard dans la v7.2.


@jmarkmurphy est correct, je viens de l'essayer sur 7.2 et cela fonctionne bien. Je modifierai ma réponse.



1
votes

Vos déclarations devraient fonctionner correctement. Voici un test de mon IBM i à v7.2, mais il devrait fonctionner de la même manière à v7.1, ou du moins jusqu'à v5r3 en fonction de la documentation que je peux trouver.

FIELD1      FIELD2      
------------------------
rowb        sissy       
row1        mama        
row2        papa        
rowa        timmy       

puis

select * 
from (
  select * from tablea
  union
  select * from tableb) a

donne :

FIELD1      FIELD2      
------------------------
rowb        sissy       
row1        mama        
row2        papa        
rowa        timmy       

et

with cte as (
  select * from tablea
  union
  select * from tableb)
select * from cte;

donne

FIELD1      FIELD2      
------------------------
row1        mama        
rowb        sissy       
row2        papa        
rowa        timmy       

et

select * from tablea
union
select * from tableb;

donne

create table tablea
  (field1    Char(10),
   field2    Char(10));
create table tableb
  (field1    Char(10),
   field2    Char(10));
insert into tablea
  values ('row1', 'mama'),
         ('row2', 'papa');
insert into tableb
  values ('rowa', 'timmy'),
         ('rowb', 'sissy');

p >


0 commentaires

1
votes

Eh bien, apparemment, le système est en fait la version 5.1, pas la version 7.1 comme je l'avais dit dans un commentaire. J'ai confondu ma version de System i Navigator pour la version du moteur de base de données (ou du système d'exploitation, ou quoi que ce soit). Pour autant que je sache, c'est la version vraiment ancienne qui pose problème.


0 commentaires