J'ai la requête suivante qui unit deux requêtes plus petites:
type | somefield | some_id --------------------------------------------- Static 1 | | 1 Static 2 | | 1
Si la requête renvoie une ligne et que la requête 2 retourne une ligne, j'aurai deux lignes comme celle-ci:
type | somefield | some_id --------------------------------------------- Static 1 | somevalue | 1 Static 2 | somevalue | 1
Quelle est la sortie que je veux. Si l'une de ces deux requêtes ne renvoie pas de ligne (ou même si les deux ne renvoient pas de ligne), aucune ligne ne sera renvoyée. Ce n'est pas ce que je veux. Je veux toujours que le 'type' et le 'some_id' reviennent même s'il n'y a pas de données. Donc, si ces deux requêtes ne contenaient aucune donnée, mon résultat attendu serait:
SELECT 'Static 1' type, somefield, some_id FROM (SELECT some_id, somefield FROM sometable WHERE someothercolumn = 'Static 1' and someid = :id) UNION ALL SELECT 'Static 1' type, somefield, some_id FROM (SELECT some_id, somefield FROM sometable WHERE someothercolumn = 'Static 2' and someid = :id)
J'ai essayé de UNION ALL chaque requête avec un NOT EXISTS mais de cette façon le ' some_id
'devrait être une valeur arbitraire codée en dur. Ce que je veux, c'est qu'il affiche toujours la variable de liaison passée, :id
.
3 Réponses :
Une option consiste à sélectionner la ligne factice d'en-tête avec le NOT EXISTS
pour décider de la retourner (oui, si la ligne réelle du tableau n'existe pas; non, si la ligne existe).
Regardez l'exemple: voir la ligne # 4 qui est commentée pour le moment ce qui signifie que votre table ne contient pas de ligne qui satisfait à cette condition, donc un en-tête factice / em> sera affiché:
SQL> with test (type, some_id) as 2 (select 'Static 99', 44 from dual union all 3 select 'Static 2' , 57 from dual 4 union all select 'Static 1', 66 from dual -- toggle to see the difference 5 ) 6 -- This is a header which won't be displayed if table contains 7 -- type = 'Static 1' and some_id = 66 8 select 'Static 1' type, 1 some_id 9 from dual 10 where not exists (select null 11 from test 12 where type = 'Static 1' 13 and some_id = 66 14 ) 15 union all 16 -- This returns actual rows (if they exist) 17 select 'Static 1' type, some_id 18 from (select some_id 19 from test 20 where type = 'Static 1' 21 and some_id = 66 22 ); TYPE SOME_ID -------- ---------- Static 1 66 SQL>
Cependant, s'il existe (ligne n ° 4 non commentée), alors les données réelles sont affichées, sans cette ligne d'en-tête factice: p >
SQL> with test (type, some_id) as 2 (select 'Static 99', 44 from dual union all 3 select 'Static 2' , 57 from dual 4 --union all select 'Static 1', 66 from dual -- toggle to see the difference 5 ) 6 -- This is a header which won't be displayed if table contains 7 -- type = 'Static 1' and some_id = 66 8 select 'Static 1' type, 1 some_id 9 from dual 10 where not exists (select null 11 from test 12 where type = 'Static 1' 13 and some_id = 66 14 ) 15 union all 16 -- This returns actual rows (if they exist) 17 select 'Static 1' type, some_id 18 from (select some_id 19 from test 20 where type = 'Static 1' 21 and some_id = 66 22 ); TYPE SOME_ID -------- ---------- Static 1 1 SQL>
Si cela fait ce que vous voulez, appliquez le même principe à la deuxième sélection
que vous utilisez (à Statique 2
) .
Peut-être quelque chose comme:
WITH a AS (/* subquery 1 */), b AS (/* subquery 2 */) SELECT (SELECT a.col1 FROM a), (SELECT a.col2 FROM a), ... FROM dual UNION ALL SELECT (SELECT b.col1 FROM b), (SELECT b.col2 FROM b), ... FROM dual
J'obtiens que VALUES (1) n'est pas une table valide
Oh, vous utilisez Oracle, qui n'implémente pas la norme là-bas. Utilisez alors dual
, comme dans ma réponse mise à jour.
Créez un CTE pour votre requête et un autre CTE pour les 2 lignes supplémentaires et utilisez UNION ALL et NOT EXISTS comme ceci:
WITH cte1 AS ( <your query here> ), cte2 AS ( SELECT 'Static 1' type, null somefield, :id FROM dual UNION ALL SELECT 'Static 2' type, null somefield, :id FROM dual ) SELECT * FROM cte1 UNION ALL SELECT * FROM cte2 WHERE NOT EXISTS (SELECT 1 FROM cte1)
J'ai essayé cette approche. Cela semble toujours être exactement le même que j'avais auparavant. Qu'il ne renvoie pas les 2 lignes attendues lorsqu'une ou les deux requêtes ne retourne aucune ligne. Donc, si une requête retourne une ligne, elle retournera cela, si aucune ne retourne, elle ne retournera aucune ligne au lieu des 2 lignes voulues.
Ce code renverra ces 2 lignes uniquement si vos deux requêtes ne renvoient aucune ligne. Si vous pouviez créer un violon avec des exemples de données, je peux le tester.
Montrez-nous quelques exemples de données de table et le résultat attendu. (Jetez un œil à l ' exemple reproductible minimal .)
utilisez
IS NULL
si rien n'est renvoyé, ou une expression pour le forcer.