Een subquery is een krachtige manier om de gegevens te vinden die u voor een andere query wilt gebruiken. Ze worden vaak gebruikt in SELECT- en UPDATE-instructies om deze zoekopdrachten efficiënter en gemakkelijker te onderhouden te maken.
Er zijn verschillende manieren om subquery's in UPDATE-instructies te gebruiken. Laten we ze allemaal eens bekijken.
SET en subquery
De eerste methode die we zullen bekijken, is het gebruik van een subquery in de SET-component van een UPDATE-instructie.
Laten we zeggen dat we een tabel met producten hadden die er zo uitzag:
[tabel id=29 /]
Het slaat een paar stukjes informatie op over verschillende producten die een bedrijf verkoopt.
Stel dat het bedrijf heeft besloten om de prijs van het product "Couch" (product-ID 1) te verhogen. In plaats van een specifieke prijs vast te stellen, willen ze deze 20% hoger maken dan het duurste product dat ze hebben.
Om dit te doen, kunnen we een subquery gebruiken in de SET-component. We zouden afzonderlijke verklaringen kunnen gebruiken, maar het is gemakkelijker om een enkele verklaring te gebruiken.
Onze verklaring zou er als volgt uitzien:
UPDATE product SET price = ( SELECT MAX(price) * 1.2 FROM product ) WHERE product_id = 1;
U kunt zien dat de SET-clausule een subquery bevat, die de MAX-waarde van de prijskolom in de producttabel vindt en deze met 1,2 vermenigvuldigt om 20% op te tellen. Ten slotte bevindt de WHERE-component zich buiten de subquery om alleen de product_id van 1 bij te werken, omdat deze van toepassing is op UPDATE in plaats van op de subquery.
Dit resulteert in de volgende wijziging:
[tabel id=30 /]
SET en gecorreleerde subquery
Een andere manier om een subquery in een UPDATE-statement te gebruiken, is door een gecorreleerde subquery te gebruiken.
Het werkt op dezelfde manier als het vorige voorbeeld. Een gecorreleerde subquery is echter een subquery die verwijst naar de buitenste instructie en kan deel uitmaken van een UPDATE-instructie.
Met behulp van de gegevens uit het vorige voorbeeld (de producttabel), wil het bedrijf alle producten deactiveren waarvoor geen bestelling is geplaatst. De gegevens hiervoor worden opgeslagen in de tabel order_line.
Als we het als een gecorreleerde subquery hebben geschreven, ziet de query er als volgt uit:
UPDATE product p SET active = ( SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END FROM order_line o WHERE o.product_id = p.product_id );
De subquery voert een COUNT-functie uit met behulp van een CASE-instructie om te bepalen of de geretourneerde waarde Y of N is, afhankelijk van de waarde van COUNT. Het wordt berekend voor elke product_id en komt overeen met de buitenste zoekopdracht.
Hierdoor wordt de actieve kolom voor sommige producten ingesteld op Y en voor andere op N:
[tabel id=31 /]
WAAR Groter dan subquery
Het is ook mogelijk om een subquery in de WHERE-component te gebruiken. Net als in de vorige voorbeelden, kan dit worden gedaan om de afzonderlijke stap van het vinden van een waarde die moet worden bijgewerkt te verwijderen en vervolgens de query uit te voeren om deze bij te werken.
We kunnen verder werken met ons voorbeeld uit de vorige stappen. Stel dat het bedrijf producten wil activeren die een bovengemiddelde prijs hebben. Om dit te doen, kunnen we een subquery toevoegen aan de WHERE-component.
Deactiveer eerst alle producten.
UPDATE product SET active = ’N’;
Werk vervolgens de tabel bij met onze subquery.
UPDATE product SET active = 'Y' WHERE price > ( SELECT AVG(price) FROM product );
Hierdoor wordt de actieve waarde ingesteld op Y voor alle records met een prijs boven het gemiddelde.
De tabel ziet er nu als volgt uit:
[tabel id=32 /]
Het toont 2 records met een actieve waarde van Y omdat ze boven het gemiddelde liggen.
Dit soort query kan ook worden uitgevoerd met andere operators die een enkele waarde toestaan, zoals
WAAR IN Subquery
We kunnen ook een subquery gebruiken met een IN-operator in de WHERE-component.
Dit is vergelijkbaar met het vorige voorbeeld waarin de operator groter dan voor een enkele waarde werd gebruikt. De IN-operator kan op meerdere waarden worden toegepast.
Laten we zeggen dat het bedrijf de prijs wilde bijwerken van sommige producten die het enige item in de categorie waren. De prijzen zouden gehalveerd moeten worden.
Onze vraag zou er als volgt uit kunnen zien:
UPDATE product SET price = price / 2 WHERE category_id IN ( SELECT category_id FROM product GROUP BY category_id HAVING COUNT(*) = 1 );
De subquery vindt alle category_id-waarden waarbij COUNT 1 is. We hoeven COUNT niet te hebben in het SELECT-gedeelte van de subquery, maar als we dat wel doen, geeft de query een fout weer.
De UPDATE-instructie werkt de prijs bij waar de categorie voldoet aan de criteria van de subquery.
Onze resultaten zien er dan als volgt uit:
[tabel id=33 /]
De gegevens lijken erg op elkaar. De prijs van het product met een categorie-ID van 1 is echter geüpdatet tot de helft van de oorspronkelijke prijs, omdat dit het enige product in zijn categorie is.
UPDATE subquery
Ten slotte kunt u een subquery in een UPDATE-instructie gebruiken om de tabel bij te werken.
In de vorige voorbeelden hebben we zojuist de producttabel gebruikt. U kunt echter een subquery gebruiken in plaats van de producttabel, die een resultatenset retourneert die kan worden bijgewerkt.
De resultatenset moet kunnen worden bijgewerkt, vergelijkbaar met het geval wanneer u een VIEW-object maakt en probeert bij te werken. Het moet eenvoudig zijn en de primaire sleutel hebben.
Dus, gebruik onze eerdere voorbeelden, stel dat het bedrijf de categorie wil veranderen voor alle producten die in categorie 4 vallen in categorie 5.
Onze vraag zou er als volgt uit kunnen zien:
UPDATE ( SELECT product_id, category_id FROM product) SET category_id = 5 WHERE category_id = 4;
Het is een eenvoudig voorbeeld dat het concept demonstreert. De tabel is vervangen door de SELECT-instructie die slechts twee kolommen van de tabel toont.
De resultaten van deze zoekopdracht zijn:
[tabel id=34 /]
Hetzelfde resultaat kan worden verkregen door de WHERE-component naar de UPDATE-instructie te verplaatsen:
UPDATE ( SELECT product_id, category_id FROM product WHERE category_id = 4) SET category_id = 5;
Conclusie
Het gebruik van een subquery in een UPDATE-statement kan een goede manier zijn om de onderhoudbaarheid van uw queries te verbeteren. Het kan ook het aantal stappen verminderen dat nodig is om uw gegevens bij te werken door twee of meer query's in één query te comprimeren.