APPLY relational operator

Έχουν δημοσιευτεί 19 Νοεμβρίου 05 12:42 πμ | KelMan 

Ένας από τους κυριότερους λόγους που πολλοί developers καταφεύγουν στους cursors όταν γράφουν T-SQL κώδικα είναι η αδυναμία να σκεφτούν τη λύση του προβλήματος με set-oriented τρόπο. Μια κλασική περίπτωση που συμβαίνει αυτό είναι το «θέλω για κάθε εγγραφή από τον πίνακα Χ να συμβαίνει κάτι στο πίνακα Υ».

Ο APPLY operator είναι ένας νέος relational operator που έρχεται να βοηθήσει όταν αντιμετωπίζουμε τέτοια προβλήματα, ώστε να μην χρειαστεί να καταφύγουμε σε cursors. Χρησιμοποιείται στο FROM clause και μας επιτρέπει να εφαρμόσουμε ένα table expression για κάθε εγγραφή του εξωτερικού πίνακα, όπου table expression μπορεί να είναι ένα view, ένας πίνακας ή ένα table function.

Ας δούμε ένα παράδειγμα:

Θέλουμε ένα report όπου για κάθε κατηγορία προϊόντων θα εμφανίζονται τα 3 πιο ακριβά προϊόντα.

Αρχικά, ορίζουμε το table function το οποίο έχει ως παράμετρο το CategoryID και βάσει αυτού φέρνει με TOP(3) τα τρία ακριβότερα προϊόντα.

CREATE FUNCTION MostExpensiveProducts(@CatID int
RETURNS TABLE AS
RETURN
  SELECT TOP (3) ProductID, ProductName, UnitPrice
  FROM dbo.Products
  WHERE CategoryID = @CatID
  ORDER BY UnitPrice DESC

Κατόπιν είμαστε έτοιμοι να γράψουμε το query μας:

SELECT CategoryName, MEP.ProductName, MEP.UnitPrice
FROM Categories 
CROSS APPLY MostExpensiveProducts(CategoryID) AS MEP

Και το output για μερικούς-μερικούς που δεν έχουν εγκαταστήσει SQL Server 2005 ακόμη!

CategoryName    ProductName                              UnitPrice
--------------- ---------------------------------------- ---------------------
Beverages       Côte de Blaye                            263.50
Beverages       Ipoh Coffee                              46.00
Beverages       Chang                                    19.00
Condiments      Vegie-spread                             43.90
Condiments      Northwoods Cranberry Sauce               40.00
Condiments      Sirop d'érable                           28.50
Confections     Sir Rodney's Marmalade                   81.00
Confections     Tarte au sucre                           49.30
Confections     Schoggi Schokolade                       43.90
Dairy Products  Raclette Courdavault                     55.00
Dairy Products  Queso Manchego La Pastora                38.00
Dairy Products  Gudbrandsdalsost                         36.00
Grains/Cereals  Gnocchi di nonna Alice                   38.00
Grains/Cereals  Wimmers gute Semmelknödel                33.25
Grains/Cereals  Gustaf's Knäckebröd                      21.00
Meat/Poultry    Thüringer Rostbratwurst                  123.79
Meat/Poultry    Mishi Kobe Niku                          97.00
Meat/Poultry    Alice Mutton                             39.00
Produce         Manjimup Dried Apples                    53.00
Produce         Rössle Sauerkraut                        45.60
Produce         Uncle Bob's Organic Dried Pears          30.00
Seafood         Carnarvon Tigers                         62.50
Seafood         Ikura                                    31.00
Seafood         Gravad lax                               26.00

Το σημαντικό εδώ είναι ότι έχουμε τη δυνατότητα να περνάμε τα πεδία από την εγγραφή του αριστερού πίνακα προς τον δεξιό πίνακα, δηλαδή για κάθε εγγραφή του πίνακα Categories περνάμε το CategoryID ως παράμετρο στο table-function. Επίσης, αν υποθέσουμε ότι είχαμε κάποια κατηγορία προϊόντων, χωρίς όμως προϊόντα, θα μπορούσαμε να χρησιμοποιήσουμε το OUTER APPLY ώστε να εμφανιστεί και αυτή η κατηγορία, με nulls όμως στα πεδία ProductName και UnitPrice.


 

Δημοσίευση στην κατηγορία:

Σχόλια:

Χωρίς Σχόλια
Έχει απενεργοποιηθεί η προσθήκη σχολίων από ανώνυμα μέλη

Search

Go

Συνδρομές