Est-il possible qu'une sous-requête renvoie plusieurs colonnes dans Oracle db? (Je sais que ce SQL spécifique va provoquer une erreur, mais il résume bien ce que je veux)
select
a.x,
( select b.y, b.z from b where b.v = a.v),
from a
Je veux un résultat comme celui-ci:
a.x | b.y | b.z
---------------
1 | 2 | 3
Je sais qu'il est possible de résoudre ce problème par des jointures, mais ce n'est pas ce que je demande.
Ma question est simplement s'il y a un moyen, d'obtenir deux ou plusieurs valeurs d'une sous-requête? Peut-être une solution de contournement utilisant dual? Alors qu'il n'y a PAS de jointure réelle, mais une nouvelle sous-requête pour chaque ligne?
EDIT: Ceci est une question de principe. Vous pouvez résoudre tous ces problèmes en utilisant join, je sais. Vous n'avez pas du tout besoin de sous-requêtes de ce type (pas même pour une colonne). Mais ils sont là. Alors, puis-je les utiliser de cette façon ou est-ce tout simplement impossible?
Une sous-requête dans la clause Select, comme dans votre cas, est également appelée une sous-requête scalaire, ce qui signifie qu'il s'agit d'une forme d'expression. Cela signifie qu'il ne peut renvoyer qu'une seule valeur.
Je crains que vous ne puissiez pas renvoyer plusieurs colonnes d'une même sous-requête Scalar, non.
En savoir plus sur les sous-requêtes Oracle Scalar:
http://docs.Oracle.com/cd/B19306_01/server.102/b14200/expressions010.htm#i1033549
C'est incorrect, mais vous pouvez essayer:
select
a.x,
( select b.y from b where b.v = a.v) as by,
( select b.z from b where b.v = a.v) as bz
from a
vous pouvez également utiliser une sous-requête dans join
select
a.x,
b.y,
b.z
from a
left join (select y,z from b where ... ) b on b.v = a.v
ou
select
a.x,
b.y,
b.z
from a
left join b on b.v = a.v
Voici deux méthodes pour obtenir plus d'une colonne dans une sous-requête scalaire (ou une sous-requête en ligne) et interroger la table de recherche une seule fois. C'est un peu compliqué mais peut être très efficace dans certains cas particuliers.
Vous pouvez utiliser la concaténation pour obtenir plusieurs colonnes à la fois :
SELECT x,
regexp_substr(yz, '[^^]+', 1, 1) y,
regexp_substr(yz, '[^^]+', 1, 2) z
FROM (SELECT a.x,
(SELECT b.y || '^' || b.z yz
FROM b
WHERE b.v = a.v)
yz
FROM a)
Vous devez vous assurer qu'aucune colonne de la liste ne contient le caractère de séparation.
Vous pouvez également utiliser objets SQL :
CREATE OR REPLACE TYPE b_obj AS OBJECT (y number, z number);
SELECT x,
v.yz.y y,
v.yz.z z
FROM (SELECT a.x,
(SELECT b_obj(y, z) yz
FROM b
WHERE b.v = a.v)
yz
FROM a) v
Ne pouvez-vous pas utiliser JOIN comme celui-ci?
SELECT
a.x , b.y, b.z
FROM a
LEFT OUTER JOIN b ON b.v = a.v
(Je ne connais pas la syntaxe Oracle. J'ai donc écrit la syntaxe SQL)
vous pouvez utiliser cross apply
:
select
a.x,
bb.y,
bb.z
from
a
cross apply
( select b.y, b.z
from b
where b.v = a.v
) bb
S'il n'y aura pas de ligne de b à mach rangée de a alors cross apply
ne renverra pas de ligne. Si vous avez besoin de telles lignes, utilisez outer apply
Si vous devez rechercher une seule ligne spécifique pour chacune des lignes de a , essayez:
cross apply
( select top 1 b.y, b.z
from b
where b.v = a.v
order by b.order
) bb
En requête Oracle
select a.x
,(select b.y || ',' || b.z
from b
where b.v = a.v
and rownum = 1) as multple_columns
from a
peut être transformé en:
select a.x, b1.y, b1.z
from a, b b1
where b1.rowid = (
select b.rowid
from b
where b.v = a.v
and rownum = 1
)
Est utile lorsque nous voulons éviter la duplication pour la table A . De même, nous pouvons augmenter le nombre de tables:
.... where (b1.rowid,c1.rowid) = (select b.rowid,c.rowid ....
Consultez ce site Web: http://www.w3resource.com/sql/subqueries/multiplee-row-column-subqueries.php
Exemple d'utilisation
sélectionnez ord_num, agent_code, ord_date, ord_amount
des commandes
where (agent_code, ord_amount) IN
(SELECT agent_code, MIN (ord_amount)
DE COMMANDES
GROUP BY agent_code);