Référence parent colonne de requête dans la sous-requête (Oracle)
Comment puis-je faire référence à une colonne à l'extérieur d'une sous-requête à l'aide d'Oracle? J'ai particulièrement besoin de l'utiliser dans la déclaration de la sous-requête.
Fondamentalement, j'ai ceci:
SELECT Item.ItemNo, Item.Group
FROM Item
LEFT OUTER JOIN (SELECT Attribute.Group, COUNT(1) CT
FROM Attribute
WHERE Attribute.ItemNo=12345) A ON A.Group = Item.Group
WHERE Item.ItemNo=12345
J'aimerais changer WHERE Attribute.ItemNo=12345
à WHERE Attribute.ItemNo=Item.ItemNo
dans la sous-requête, mais je ne peux pas savoir si c'est possible. Je reçois des "ORA-00904: 'Item'.'ItemNo': Identificateur Non Valide"
EDIT:
Ok, c'est pourquoi j'ai besoin de ce genre de structure:
Je veux être en mesure d'obtenir un décompte de l ' "Erreur" des dossiers (où l'élément est manquant une valeur) et le "OK" des dossiers (où l'élément a une valeur).
La façon dont je l'ai mis dans le violon renvoie les données correctes. Je pense que je pourrais juste en fin de remplissage de la valeur dans chacun des sous-requêtes, puisque ce serait probablement le moyen le plus facile. Désolé si mes structures de données sont un peu alambiqué. Je peux expliquer si besoin.
Mes tableaux sont:
create table itemcountry(
itemno number,
country nchar(3),
imgroup varchar2(10),
imtariff varchar2(20),
exgroup varchar2(10),
extariff varchar2(20) );
create table itemattribute(
attributeid varchar2(10),
tariffgroup varchar2(10),
tariffno varchar2(10) );
create table icav(
itemno number,
attributeid varchar2(10),
value varchar2(10) );
et ma requête jusqu'à présent est:
select itemno, country, imgroup, imtariff, im.error "imerror", im.ok "imok", exgroup, extariff, ex.error "exerror", ex.ok "exok"
from itemcountry
left outer join (select sum(case when icav.itemno is null then 1 else 0 end) error, sum(case when icav.itemno is not null then 1 else 0 end) ok, tariffgroup, tariffno
from itemattribute ia
left outer join icav on ia.attributeid=icav.attributeid
where (icav.itemno=12345 or icav.itemno is null)
group by tariffgroup, tariffno) im on im.tariffgroup=imgroup and imtariff=im.tariffno
left outer join (select sum(case when icav.itemno is null then 1 else 0 end) error, sum(case when icav.itemno is not null then 1 else 0 end) ok, tariffgroup, tariffno
from itemattribute ia
left outer join icav on ia.attributeid=icav.attributeid
where (icav.itemno=12345 or icav.itemno is null)
group by tariffgroup, tariffno) ex on ex.tariffgroup=exgroup and extariff=ex.tariffno
where itemno=12345;
Il est également mis en place dans un SQL Violon.
- vous ne pouvez pas.. que voulez-vous sélectionner? peut-être une autre solution autre que de la jointure externe gauche.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez le faire dans une sous-requête, mais pas dans une jointure. Dans votre cas, je ne vois pas le besoin. Vous pouvez le mettre dans la condition de jointure.
L'optimiseur est construit pour gérer ce type de situation afin de l'utiliser!
J'ai changé le
count(1)
à ungroup by
que vous avez besoin degroup by
toutes les colonnes qui ne sont pas agrégés.Je suis en supposant que votre requête réelle est plus compliquée que ce que les colonnes que vous êtes en sélectionnant c'est probablement équivalent à
Vous pouvez également écrire votre sous-requête avec un
analytique de la fonction
à la place. Quelque chose commecount(*) over ( partition by group)
.Comme une part à l'aide d'un mot clé comme nom de colonne, dans ce cas
group
est Une Mauvaise Idée TM. Il peut causer beaucoup de confusion. Comme vous pouvez le voir dans le code ci-dessus, vous avez beaucoup degroups
là.Sur la base de votre SQL-Violon, que j'ai ajouté à la question, je pense que vous êtes à la recherche de quelque chose comme la suivante, qui n'a pas l'air beaucoup mieux. Je soupçonne que, étant donné le temps, je pourrais faire plus simple. Sur une autre note de côté explicitement boîtier inférieur requêtes n'est jamais en valeur la dispute qu'elle provoque. J'ai suivi votre convention de nommage bien.
Vous pouvez le mettre OÙ attribut.itemno=élément.itemno à l'intérieur de la sous-requête. Vous allez filtrer les données de toute façon, le filtrage des données à l'intérieur de la sous-requête est généralement plus rapide aussi.